How to fix the “Render blocking Javascript and CSS in above the fold content” google Pagespeed issue


Disclaimer – this is pulled directly from this post from Akeel.co.uk which is now throwing a 404 error – I’ve re-posted it here for my own reference.


What’s above the fold content?

Above the fold content is the part of the page that is visible in the browser window when the page first loads. With the trend towards mobile web browsing, this is more crucial now due to the limited speeds of mobile networks. But also, due to the modern web design trends of today requiring increasingly more scripts on the page than ever before.

Fixing the CSS

So what we need to achieve here is to get a copy of the crucial CSS required to display the top portion of your page in-lined into the head tag of your HTML.

You could obviously spend a lot of time trying to tag all of the CSS that affects this part of your page, or tediously go through and extract the exact portions that you require. But that’s not really a maintainable or efficient way of approaching this problem, and it’s obviously a method that would be prone to error. Instead, I’ll be looking at a node.js tool called Critical by Addy Osmani.

If you don’t already have node.js, you’ll want to download that for your platform here.

This tool requires an html file with a copy of your CSS files. I found the easiest way to get this was to browse to your site in Chrome (or other browser) and save the page in the file menu, ensuring you save a complete copy into a directory of your choosing.

Navigate to that browser in your console and using npm (a package manager for node), save critical to your directory with the following command:

npm install --save critical

Once that’s completed, you’ll need to create a .js file that will import Critical, define your desired settings and generate your files.

This is my .js file:


var critical = require('critical');

critical.generate({
    // Inline the generated critical-path CSS
    // - true generates HTML
    // - false generates CSS
    inline: true,

    // HTML source file
    src: 'Akeel - Fullstack Developer.html',

    // Your CSS Files (optional)
    css: ['Akeel - Fullstack Developer_files/style.css'],

    // Viewport width
    width: 1300,

    // Viewport height
    height: 900,

    // Target for final HTML output.
    // use some CSS file when the inline option is not set
    dest: 'index-critical.html',

    // Minify critical-path CSS when inlining
    minify: true,

    // Extract inlined styles from referenced stylesheets
    extract: true,

    // Complete Timeout for Operation
    timeout: 30000,

    // Prefix for asset directory
    pathPrefix: '/Akeel - Fullstack Developer_files',

    // ignore CSS rules
    ignore: ['font-face',/some-regexp/],

    // overwrite default options
    ignoreOptions: {}
});
	

The comments will help you figure out what settings are best for you.

You can then run that file using node, something like:

node critical.js

This will generate the html file with the in-lined styles to your specified destination html file. Copy that style tag from the generated file into the header of the site. So now we have the critical above-the-fold CSS in-lined into the header of your site.

Deferring loading of your main stylesheet

So we’ve now got the critical part of your CSS loaded into your header. But you’re still probably loading the stylesheet synchronously, blocking the page. Let’s look at deferring the loading of the stylesheet. You will need to remove the existing link to your stylesheet and this time in the footer of your page add the following:


    <noscript id="deferred-styles">
        <link href="/assets/styles.css" rel="stylesheet">
    </noscript>
    <script>
      var loadDeferredStyles = function() {
        var addStylesNode = document.getElementById("deferred-styles");
        var replacement = document.createElement("div");
        replacement.innerHTML = addStylesNode.textContent;
        document.body.appendChild(replacement)
        addStylesNode.parentElement.removeChild(addStylesNode);
      };  
      var raf = requestAnimationFrame || mozRequestAnimationFrame ||
          webkitRequestAnimationFrame || msRequestAnimationFrame;
      if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); }); 
      else window.addEventListener('load', loadDeferredStyles);
    </script>
   

The code within the script tag should remain as is, but you should add any stylesheets you have within the noscript tag. And that’s it for the CSS.

Deferring JavaScript files

This is a lot simpler and you can simply move your js scripts into the footer using the code below as an example.


<script type="text/javascript">
    function deferJS() {
        var element = document.createElement("script");
        element.src = "defer.js";
        document.body.appendChild(element);
    }
    if (window.addEventListener)
        window.addEventListener("load", deferJS, false);
    else if (window.attachEvent)
        window.attachEvent("onload", deferJS);
    else window.onload = deferJS;
</script>
   

Now you should be able to run your site against the PageSpeed Insights tool and see an improved result.