Pagespeed Fix: Eliminate Render-blocking JavaScript and CSS

by Jeremias Duarte. .





Everyone that uses Google’s Pagespeed Insights tool has encountered this error. The worst part of attempting to fix this error is the fact that Google’s advice on how to solve the issue is of little or no help. Google’s example shows a block of HTML that includes the CSS tag within a ‘noscript’ tag, strategically located outside of the HTML tags. I found that using that technique adequately resolved the error. However, the ultimate result was that the CSS was no longer rendered in the browser…

The Issue

The reason that Google recommends fixing this is not because of an actual error in the web page markup. The recommendation actually attempts to speed up the page rendering process by allowing the user to begin reading content, text, images, etc. without fully downloading the page.
For example, let’s say you download a web page that uses 4 different CSS files to style the content. When you make the request in your browser, your browser will actually wait until it has all 4 files before it shows you the page. Ideally, the browser would render everything it downloads first (i.e. HTML and text), while continuing to download all of the other components of the web page (i.e. images, JavaScript, CSS, etc.). However, the question remains, how do we do that?

The Solution

The solution to render-blocking CSS is a concept called asynchronous downloading. JavaScript has an available attribute called “asyc” that you can add to the JavaScript tag, which tells the browser to download the script in an asynchronous manner. However, the “link” tag used to include CSS doesn’t have such an attribute. The solution I chose was to use javascript to asynchronously write the CSS to the web page, thereby reducing the time it takes for a user to view the web page – and, no more Pagespeed suggestions.

Note: I strongly suggest you consolidate all of your CSS into a single file. This will allow you to include the script once on your web page. If you choose not to consolidate your CSS, you must run this script for every individual CSS file for it to function.

You can take the JavaScript from the code below and paste it directly into the HTML of your web page. I would suggest including it in the footer section of the page, just before the last “body” tag. Replace “/style.css” with the relative location of your CSS file. For example, if your CSS file is located in the “/css/” folder relative to the website root and named “sheet.css”, you would replace the “/style.css” with “/css/sheet.css”. When the page is downloaded, the browser will make an asynchronous GET request for the CSS file. It then writes the raw CSS to a “span” tag with an id of “noblock”.

function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("noblock").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/style.css",true);
xmlhttp.send();
}

Next, copy and paste the following “span” tag somewhere towards the opening “body” tag. That’s it!

<span id="noblock"></span>

Summary

The key to successfully preventing render-blocking CSS and JavaScript above the fold is using a process known as asynchronous downloading. Using the JavaScript method above, you are able to allow CSS to be downloaded and rendered in the background, while the viewer can begin reading. This method can also be used with jQuery by applying the same concept. In addition to using an asynchronous download, this method also reduces the initial number of HTTP requests for above the fold content.