2

I have a Ruby on Rails app. For my views i am using react-rails gem. I want to improve pagespeed through Google PageSpeed. My main problem is Remove Render-Blocking JavaScript so i added async: true to my javascript_include_tag helper method. Then when i refresh site i have blank white window browser with these messages inside console:

ReferenceError: $ is not defined
   $(document).ready(ready);
ReferenceError: jQuery is not defined
   }(jQuery);

ReferenceError: jQuery is not defined
   })( jQuery );

ReferenceError: React is not defined
    this.About = React.createClass({

My applicaton.js file:

//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require react
//= require react_ujs
//= require semantic-ui
//= require components
//= reqiore custom
//= require_tree .

var ready;
ready = function() {

};

$(document).ready(ready);
$(document).on('page:load', ready);

What i need to do in order to remove blocking javascript?

Panczo
  • 424
  • 5
  • 20

1 Answers1

1

Since virtually everything on the page is dependent on JQuery, any successful page rendering needs JQuery to be loaded to start. Therefore in my experience there is no way around the blocking Javascript.

From a user's perspective, putting in a lot of work to prevent JQuery blocking may allow the DOM to load, but it will probably do a lot of jumping around after Jquery and all related plugins have loaded as the DOM gets rewritten, making the experience worse than a marginally longer page load.

Overall, I'd focus efforts on ensuring your JQuery and all related JS and CSS files are delivered through a CDN, so you can benefit from HTTP pulling from a second domain in parallel to your primary, and to ensure you do nothing to break browser caching of the JQuery and other assets so they do not block on subsequent request.

EDIT

I also meant to mention that it is worth testing with your assets precompiled (which is necessary anyway if using a CDN), switching off asset live compilation for missing items with

config.assets.compile = false

This will prevent any missing assets causing confusing delays, and possibly invalid compilations once your are live.

An additional note regarding serving assets from your web server:

According to http://guides.rubyonrails.org/asset_pipeline.html

4.1.1 Far-future Expires Header

Precompiled assets exist on the file system and are served directly by your web server. They do not have far-future headers by default, so to get the benefit of fingerprinting you'll have to update your server configuration to add those headers.

For Apache:

# The Expires* directives requires the Apache module
# `mod_expires` to be enabled.
<Location /assets/>
  # Use of ETag is discouraged when Last-Modified is present
  Header unset ETag
  FileETag None
  # RFC says only cache for 1 year
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
</Location>

For NGINX:

location ~ ^/assets/ {
  expires 1y;
  add_header Cache-Control public;

  add_header ETag "";
  break;
}

Finally, make sure you test running on a server that mimics your eventual production environment, as Rails development servers are not going to provide the same responsiveness.

Phil
  • 2,797
  • 1
  • 24
  • 30