Three Ways to Remove Render-Blocking JavaScript

April 1, 2019
by
Vince Bolhuis

Using tools like Google's PageSpeed Insights to assess page performance, C2's Front-End Developer Vince Bolhius shares three different ways to pass common audit failures for eliminating render-blocking JavaScript resources.

Development
UX & Design

As the largest and most influential search engine, Google has a lot of say in the expectations on how businesses present themselves online. I’ve talked a bit about using Google’s PageSpeed Insight’s tool before and how to eliminate render-blocking CSS in above-the-fold content. Based on the reactions I received in my first blog, I thought I’d share how to pass Google’s eliminating render-blocking resources task to boost page speed performance. I highly recommend using PageSpeed Insights to audit which sources may be problematic for your page’s overall performance.

I will be showing how to pass a few common audit failures to help increase page performance.

Using the Preload Attribute for Critical Resources

Most resources that are specified within JavaScript and CSS penalize performance due to the initial shallow document parser. Thankfully, using preload attributes in the HTML head, you can define critical resources that should be fetched, including when and how each resource should be applied. Preload attributes allow you to specify resources that will be used shortly after loading them and ensure they are executed in a designated order, ultimately boosting page speed performance.

First, here’s an example of the common way to load a CSS resource into the head section of a page:

<p> CODE: https://gist.github.com/thec2group-blog/242373c788c99e7a7308cff4dbdf34c3.js</p>

Now, here’s how you can preload that request. I’ve also added a noscript fallback for browsers blocking script:

<p> CODE: https://gist.github.com/thec2group-blog/0fee2987545548c83ffbcf96fd99b498.js</p>

We specified the preload value using the rel attribute, loaded the source in the href, used the as attribute to specify what type of resource we’re preloading, and then used the onload event to load the source when it’s ready. Again, preload attributes are great to start fetching resources we know that the browser is going to need soon.

Using Webfontloader to Load Fonts into JavaScript

Another common performance ding is in the way a page loads fonts. If you’re having trouble loading external fonts like Typekit or Google Fonts, using a webfontloader allows for some added control when injecting a @font-face with JavaScript. By adding this code outside of the head section, we can mitigate penalized render-blocking of custom fonts. You’ll need to reference the JavaScript library, and then you’ll be able to add in your fonts using the WebFont object.

Check out the following webfontloader code example:

<p> CODE: https://gist.github.com/thec2group-blog/9f8a57e22bca73d279863561f15d61e1.js</p>

Simply add in your custom Google fonts into the families array or specify your Typekit id to load the external font package.

NOTE: In this instance, it is possible that the rest of the page may render before the Web Font Loader is executed, which can cause a Flash of Unstyled Text (FOUT) or Flash of Invisible Text (FOIT) so it’s important to have fallback fonts in your CSS.

Flash of Unstyled Text (FOUT) will occur when the font starts loading and immediately shows the text with the font-family fallback until the web font loads and the fallback font is replaced with the default font called from your CSS styles.

Flash of Invisible Text (FOIT) will occur when the font starts downloading and appears as non-existent until the web font loads and replaces that “invisible” text.

To account for this, I’ve added arial and sans-serif as a fallback for Google’s Open Sans font:

<p> CODE: https://gist.github.com/thec2group-blog/a366a62c227fb01853027c7758931bb7.js</p>

As I mentioned, it’s crucial to have a fallback font to rely on in your CSS styles in the case (and likelihood) the custom font is taking some time to retrieve and load. Web Font Loader will then load the actual font after JavaScript runs.

Using Async and Defer Attributes to Load Script

This is reactively easy. It’s best practice to load all script resources below the fold and above the </body> tag. This will allow the page to load first and eliminate any render-blocking from JavaScript. If that’s not possible, you may use async or defer attributes to load scripts in the <head> tag. Async and defer attributes can be used to control how and when external files are fetched and executed.

Async allows for the file to be downloaded asynchronously and then executed as soon as it’s downloaded. This means the file starts downloading while the HTML document parsers, and once downloaded, parsing is stopped for the script to execute and then continues parsing.

Using the async attribute to load a resource may look something like this:

<p> CODE: https://gist.github.com/thec2group-blog/ce99be21230c69d33a36df900201ea64.js</p>

Defer downloads the file asynchronously but is only executed after the HTML document parsing is complete. This means that the file starts downloading while the HTML document parsers, and even if finished loading, the file waits to be executed until after the HTML is fully parsed. When using defer, scripts are executed in the same order that they are called. Defer is a great option when a script depends on another script.

Below is an example of how we can use the defer attribute to load resources:

<p> CODE: https://gist.github.com/thec2group-blog/631fe1c71fb5bfa370cb38a1b0740cef.js</p>

It’s a good rule of thumb is to use async first and defer as needed and only when the <script> element is not located at the end of HTML document. In the event you have an externally sourced JavaScript file placed right before the closing </body> element, async and defer attributes won’t be needed. Since most of the HTML document has been parsed at that point, the JavaScript file doesn’t have much parsing left to block.

When it comes specifically to combating render-blocking resources, these are all great methods to improving your overall site speed and performance. To get a good overall view of your site performance, I’d suggest following through the analysis Google provides with PageSpeed Insights and apply recommendations where necessary.