I have a rails application and the application.js after asset compilation takes more than 1 MB. This is slowing down my entire site.
I use Apache, Rails 4, jQuery, quite heavy JavaScript and AJAX. I would be very grateful if someone could point me in the right direction.
This may not be feasible in your particular case, but has certainly helped me keep Application.js from bloating.
As I'm sure you know, Application.js compiles all specified files (by default, all of them) into a single .js file, which is loaded (again, by default) as part of your layout in every page. Often times this results in the inclusion of entirely unnecessary custom scripts loading in every page, and slowing down the entire application. I personally find this behavior undesirable. What I find works for my sites is only including my "core" javascript components in Application.js (jquery, bootstrap's js libraries, and any scripts that pertain to layout.html.erb itself), and specifying the rest in the pages that need them. For example:
application.js
Note that it does NOT include require tree .. This is important, as that is the line which specifies the inclusion of the entire assets/javascripts folder. "Template" in this case is the .js file a defined which pertains to layout.html.erb
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require bootstrap-sprockets
//= require template
//= require turbolinks
layout.html.erb
The following is the very end of my layout, immediately before the closing body tag. This loads application.js on every page, and after that loads any js specified in the view.
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<% if content_for?(:javascript) %>
<%= yield :javascript%>
<% end %>
The View(s)
In any view that requires page-specific javascript, you may specify the files with a Rails javascript helper
<% content_for :javascript do %>
<%= javascript_include_tag 'pages/profile', 'data-turbolinks-track' => true %>
<% end %>
initializers/assets.rb
Finally, make sure that your scripts are still being precompiled, even though they aren't a part of Application.js.
Rails.application.config.assets.precompile += %w( pages/profile.js )
...or, more efficiently assuming you have many pages with their own scripts...
Rails.application.config.assets.precompile += %w( pages/* )
In Conclusion
I find this technique really helps keep the size of Application.js down, and makes for good practice in general. I hope you find it useful, and apologize if it is extraneous to your problem.
Have you ever thought about using the CDN hosted jQuery Version? Could you provide your uncompiled application.js.
You could also try to use browserify or require.js
Related
I have put the tag javascript into my body application.
In my console I am getting this error:
Rails-ujs has already been loaded.
In development mode the app works, however it doesn't work in production.
I have deployed my rails application on Heroku.
I try to move the tag javascript into the head, but then all function js is not working.
Any solution?
If you're using webpack and a separate front-end, you might have two instances of your javascript tag in application.html.
= javascript_include_tag 'application', 'data-turbolinks-eval' => false
= javascript_pack_tag 'application'
You'll want to remove the first instance; similarly if you've used pack_tag to render your stylesheets, you may be experiencing CSS classes being called twice (you'll see stacked classes on an element in dev tools).
I solved bringing my javascript into the head and simply including all my functions below:
$ (document).on('turbolinks: load', function () {
})
If you do not use webpack then use as like:
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload', 'data-turbolinks-eval': false %>
<%= javascript_include_tag 'frontend_application', 'data-turbolinks-track': 'reload' %>
</body>
in application.js file
//= require rails-ujs
//= require activestorage
//= require turbolinks
in frontend_application.js file
//= require compress.min
//= require custom
I've got an issue that must come from my side but turning me crazy :-p
When I'm in development environment, I've to put these lines in application.html.erb to have I18n.js working :
<%= javascript_include_tag "i18n" %>
<%= javascript_include_tag "translations" %>
The problem is that on production environment, it doesn't work (it doesn't found the i18n.js, 404, I know that's normal, due to the assets pipeline), I've to put these lines in application.js :
//= require i18n
//= require i18n/translations
But if I leave these like that, I've got an error in development environment : uninitialized constant SimplesIdeias
It works for all the rest of my scripts, only i18n.js got a problem to load.
What is the way to make them both works ? :p
I've tested my Rails app's functionality by placing jQuery at the bottom of my home.html.erb file with simple script tags. Everything works fine until I attempt to utilize the Asset Pipleine in Rails 3.1 and place the script within app/javascripts/home.js.erb
Anyone know why I can't get the javascript to work outside of the home.html.erb file
you could add the script tag in the application.html.erb and you'll have jquery in all your pages.
you can add the script in this way: (you should add the jquery-1.7.min file in the folder app/javascript)
<%= javascript_include_tag 'jquery-1.7.min'%>
Don't put home.js.erb in app/javascripts but extract your jquery from home.js.erb and put in app/assets/javascripts/home.js
add config.assets.precompile += %w( *.js ) to config/environments/production.rb or in config/application.rb for global env (test/dev/prod)
than in app/assets/javascripts/application.js have
//= require jquery
//= require jquery_ujs
//= require_self
//= require_tree .
call it with javascript_include_tag "application" from the view
... and finally, don't forget to add gem 'jquery-rails' to your Gemfile and run bundle
As far as what I was looking to do, which was separate javascript files for different views, I was unsuccessful. I tried different naming conventions, etc.
What has worked for me however, is putting all of my javascript within application.js. Doing this makes this code accessible by every view throughout the entire application. Depending upon your needs and your app, you may want to put the script within [your-model-name].js.coffee which will make it accessible (I think just for your particular controllers and views). Since my app is a single model/controller setup, this is essentially the same thing.
Then, it's a matter of using selectors carefully as to not interfere with other pages unintentionally. In other words, if you want a piece of code to run within one particular view and not another, you will have to adjust your .js code accordingly, since everything within application.js is accessible to all views.
I have a problem with Rails and Jquery. Im using AJAX to add comments to articles without reloading them. The following code got automatically included in my views/application.html:
<%= javascript_include_tag "application" %>
<%= javascript_include_tag :all %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" %>
<%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" %>
Everything seemed to work fine, until i realised that the server console shows the following error:
ActionController::RoutingError (No route matches [GET] "assets/all.js")
So since this line doesn't seem to add anything to the application other than an error i deleted it. Next time I started the server and used the application all of a sudden every comment gets posted twice!? Otherwise everything still worked fine. So I added the deleted line again and I have no idea why but when I add the line
<%= javascript_include_tag :all %>
again everythings works fine again, only one comment gets posted as intended. However I dont want to keep this in the code since it throws an error. Can someone explain this behaviour and tell me how to fix this?
Rails 3.1 uses sprockets to bundle javascript and css files. This makes the :all option deprecated. Sprockets use 'magical' comments to manage which javascripts are included.
So your application.js should look something like this:
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require_tree .
The first line also includes jQuery itself, so you don't need the other script tags. All you need to to is to point to application.
<%= javascript_include_tag "application" %>
If you're deploying to production, you'll need to run rake assets:precompile.
There is a Railscasts episode on assets, which is a must see.
So I've recently started to include quite a few .js files in to my web application and some of them depend on each other so load order is important.
However rails caching just seems to load a all.js file with no particular order to the files.
What's a good way to solve this issue?
You can do as follows
First, load the default JavaScript files.
Then load other scripts in the order that you want
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag "script_1", "script_2", "script_3" %>
The load order depends on your Javascript manifest file. In Rails 3.1 you can go to
app/assets/javascripts/application.js
At the bottom of the file you will see directives for rails how what / how to include files into the Rake pipeline. In the below example, I included a new directive that will include all the files in the directory called "Templates". I also made sure that the Handlebars.js templating file is called before all of the files in the "Templates" directory, otherwise the browser would throw an exception
//= require handlebars
//= require_tree ../templates
//= require_tree .
Hope it helps!
I've been experimenting with the YUILoader Module, it seems pretty nifty, though I am currently frussing about loading up custom modules. It's totally doable, I just couldn't figure it out in 5 mins.
http://developer.yahoo.com/yui/yuiloader/ (YUI2.8.1)
http://developer.yahoo.com/yui/examples/yuiloader/index.html