How can I optimize javascript assets? - ruby-on-rails

I've already finished my project, and it seems working fine.
But, I've just found that there's more things to do with optimization.
Google's PageSpeed Insight just told me that
I have to Remove Render-Blocking JavaScripts, Optimize CSS Delivery and Leverage Browser Caching
About Remove Render-Blocking JavaScripts, and Leverage Browser Caching, it says that I have to work with my Assets Javascripts.
They are currently stated just like this in view
<%= javascript_include_tag 'application.js' %>
<%= javascript_include_tag 'illuminate.js' %>
<%= javascript_include_tag 'bootstrapSwitch.js' %>
<%= javascript_include_tag 'bootstrap.js.coffee' %>
<%= javascript_include_tag 'rails.js' %>
and its html ouput is this
<script src="/assets/application-21cb698a1b325807d74e3f5588e.js" type="text/javascript"></script>
<script src="/assets/illuminate-1a2b0535b4a3f7468aec74882e25f3.js" type="text/javascript"></script>
<script src="/assets/bootstrapSwitch-ae37e5eb28f943501b59b08ac6234.js" type="text/javascript"></script>
<script src="/assets/bootstrap-1b52926900736585a26c3fe0975f73.js" type="text/javascript"></script>
<script src="/assets/rails-e46b066113d4a1ff96120b8493021d9.js" type="text/javascript"></script>
How can I change this to change this in order to archive?
and about Optimize CSS Delivery, it says that I have to optimize these
<%= stylesheet_link_tag "application","http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css" %>
<%= stylesheet_link_tag 'bootstrapSwitch' %>
and this is its html ouput
<link href="/assets/application-e8a61afef574ba15cb71a3730d2b6b8e.css" media="screen" rel="stylesheet" type="text/css" />
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/smoothness/jquery-ui.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/assets/bootstrapSwitch-b3ea2e51b3529f79637f5a8a9ef54712.css" media="screen" rel="stylesheet" type="text/css" />
How can I modify all of these?

Try :
1) minifying your javascripts : smaller the size, the faster will your pages load
2) using a CDN to host your assets : this helps to load your assets faster and hence a better response time
3) #depa gave some nice pointers to asset pipelines in rails, check that out as well
and you'll be good.

Related

Is there a (easy) way to find the cause of a display issue on Select2?

New developper on RoR, I’m using Select2 to display some companies or departments.
Select2 was working fine for some weeks, and now, display is broken on every select2 input.
I used github history to detect why it’s failing now, but no indications of modifications which can explain that.
It's displaying a very small square or nothing. However, selecty2 is working when I click on the small square for exemple.
small square display,
Select2 working but display is broken
I used Github History pomber and inspect all files concerned. Nothing to explain why the display is broken now. Is the a way to detect the cause of the issue ?
I'm using Bootstrap 4 with rails 5.2.1
app/javascript/components/select2.js :
import $ from 'jquery';
import 'select2';
import 'select2/src/scss/core.scss';
import 'select2-bootstrap4-theme/dist/select2-bootstrap4.css';
$('.select2-form').select2({
theme: "bootstrap4"
});
// Requiring CSS! Path is relative to ./node_modules
app/javascript/packs/application.js
import '../components/select2';
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<%= csrf_meta_tags %>
<%= action_cable_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= stylesheet_pack_tag 'application', media: 'all' %>
<%= stylesheet_pack_tag 'application' %>
<!-- bootstrap animation carousel -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<!-- bootstrap animation carousel -->
<!-- Select2 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<!-- Select2 -->
</head>
<body>
<%= render 'shared/navbar' %>
<%= render 'shared/flashes' %>
<%= yield %>
<%= render 'shared/footer' %>
<%= javascript_include_tag 'application' %>
<%= javascript_pack_tag 'application' %>
<%#= javascript_pack_tag "map" %>
</body>
</html>
I expect the input should be display correctly.
If it used to work, and now it doesn't, you can git bisect to determine which commit introduced the regression. When that is done, you should be able to pinpoint the guilty piece of code, again by adding the changes in this commit one by one and see when the regression pops up. Then you might be able to understand the reason for the regression.

How do I prevent Rails from loading assets?

An understandably weird question. I'm porting a project to RoR, in order to use some of its components. Asset management is not one of them.
I wind up with something like this in my page source:
<!DOCTYPE html>
<html>
<head>
<title>Opera</title>
<link data-turbolinks-track="true" href="/assets/application.css?body=1" media="all" rel="stylesheet" />
<link data-turbolinks-track="true" href="/assets/main.css?body=1" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/jquery.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/jquery_ujs.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/turbolinks.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/main.js?body=1"></script>
<script data-turbolinks-track="true" src="/assets/application.js?body=1"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="5YFRzv/wICYBms8cregzthpFqCr5gf3pQknNpLOOeEg=" name="csrf-token" />
</head>
<body>
<!-- My scripts and stylesheets below -->
What do I do differently such that the page doesn't load its own scripts and stylesheets?
Additionally, if I link stylesheets in the .erb template, they all wind up under the <body> tag. The Rails stylesheet/script helpers assume that your stuff is in the /asset directory.
How do I get Rails to link my scripts under <head> if I've placed my scripts and stylesheets in /public?
Thanks!
The default scripts and stylesheets are loaded because of the following two lines in app/views/layouts/application.html.erb
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
Rails uses the layout defined in the file app/views/layouts/application.html.erb as a default for rendering any view. The views go in the body part of application.html.erb while rendering.
You can remove the unwanted js from app/assets/javascripts/application.js file and css from app/assets/stylesheets/application.css file. You can also specify your own assets in these two files.
I am not sure about /public level. Rails pipeline assets can be placed inside an application in one of three locations: app/assets, lib/assets or vendor/assets.
Read more details for: Rails Asset Pipeline

Why does Rails duplicate assets when using yield?

I've read and tried the solutions here (Ruby On Rails 3.1 - assets pipeline - assets rendered twice) for the duplicate assets problem in Rails, but it's not working on my scenario, which looks like this:
Layout:
<!DOCTYPE html>
<html>
<head>...</head>
<body>
...
<!-- including :application -->
<%= javascript_include_tag :application %>
<!-- yielding :body_script -->
<%= yield :body_script %>
</body>
</html>
Then, in a "users" view:
<%= content_for :body_script do %>
<%= javascript_include_tag 'users' %>
<% end %>
...
...
...
My javascript dependencies are that:
application.js "requires" jquery, bootstrap and self
users.js "requires" worker_interface.js
worker_interface.js "requires" jquery, knockout and application
When the "users" view is rendered, I'm getting duplicate jquery and application.js on the end of my body, one of each being rendered because of the javascript_include_tag :application and the other because of yield :body_script, like this:
<!-- including :application -->
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/bootstrap.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<!-- yielding :body_script -->
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/knockout.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<script src="/assets/worker_interface.js?body=1" type="text/javascript"></script>
<script src="/assets/users.js?body=1" type="text/javascript"></script>
I know that I have redundant dependencies here, because I am asking to include jquery and application more than once (indirectly). However, shouldn't Rails guarantee that no duplicate files are rendered? Can I still keep the "redundant" dependencies and have the files rendered only once?
BTW, I'm using Rails version 3.2.9.
shouldn't Rails guarantee that no duplicate files are rendered? Can I
still keep the "redundant" dependencies and have the files rendered
only once?
simple answer: no
assets are precompiled and so "static" in production. you may include assets in several ways. so there is no way for rails to "know" what files should be eliminated in the context of your rendered page.
YOU need to make sure there are not duplicates.

Managing page-specific stylesheets and javascript files with Rails 3 application layout

I'm attempting to keep the application layout in my Rails 3 app for the stylesheets and javascript files I use most frequently (application.js, jquery, style, etc.). However there are plugins I'm using on certain pages and want to include those stylesheets/javascripts properly. For example, I'm looking to use slides only on my homepage. If my application layout is like the one below, what's the best way to include page-specific files?
<!doctype html>
<head>
<title>Title</title>
<link rel="stylesheet" href="http://localhost:3000/stylesheets/style.css" media="screen and (min-width:481px)">
<!--[if IE]>
<link rel="stylesheet" href="http://localhost:3000/stylesheets/style.css" media="all"><![endif]-->
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="user-scalable=no,width=device-width">
</head>
<body>
<%= render 'layouts/header' %>
<%= yield %>
<%= render 'layouts/footer' %>
</body>
</html>

Ruby on Rails: How can I add a css file with rails project?

The application.html.erb file:
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
I have a file "cake.generic.css" in public/ folder.
But when I reload the page the effect of css file is not working.
If I see the page view source I see something like this:
<!DOCTYPE html>
<html>
<head>
<title>Site</title>
<link href="/assets/all.css" media="screen" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/home.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="6CPvchXr1amagxd7VmOzB82WGx/WmjfDOXjMLfjLzqQ=" name="csrf-token" />
</head>
<body>
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
</body>
</html>
What should I do to fix this problem?
How can I set the public folder for stylesheets and javascripts?
It looks that app/assets folder is set for css and js files?
Rails is likely consolidating all your css files into one that it is calling assets/all.css
Consider using the free plug-ins firebug + firepath to further characterize the problem. This common combo of tools will help you to interrogate web page elements and see the css that is contributing to their display.
Copy cake.generic.css to the folder public/assets/, if not exists make directory first.
then add this to you erb
<%= stylesheet_link_tag "cake.generic" %>
2nd question: How can i set the public folder for stylesheets and javascripts ?
Just put all you images, js and css file under 'public/assets/' and then include them in the erb pages
3rd question: It looks that app/assets folder is set for css and js files ?
Yes, 'app/assets/stylesheets/' for css and scss file
and 'app/assets/javascripts' for js and coffeescript file
You can get more info here: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Hope this work for you:)
Your Style sheet should be placed in the following directory \public\stylesheets from your root project and also if you want to specify different location provide an absolute path inside stylesheet_link_tag("/public/yourfolder/test.css")
I had similar issue, but my fix was to make sure the css is under app/assets/stylesheets/ and I had to add the below line to the application.css file (my css file is named custom.css)
#import 'custom'

Resources