How to Eliminate Render-Blocking JavaScript and CSS

By , Updated: September 7, 2017

eliminate render-blocking javascript

When it comes to the speed of your website, it’s important to think of speed as a necessary feature, not a luxury, and to treat it accordingly. There are a lot of things that go into the equation that determines how quickly site visitors begin to see content when they visit your website. Some of these things you can’t control: the speed of their internet connection, their geographic location, network congestion, and so forth. However, there are others things that you can and should control.

One tool you can use to identify speed-reducing issues that are under your control is Google PageSpeed Insights. Surely you’ve used PageSpeed Insights before (if you haven’t, this is your cue to head there before reading the rest of this article). It’s free and pinpoints issues that are slowing down delivery of your websites, such as render-blocking JavaScript and CSS.

Common Issue: Render-Blocking JavaScript and CSS

There are ten speed rules used to analyze sites run through PageSpeed Insights. Two of these rules have to do with JavaScript and CSS resources blocking above-the-fold content. Fail either of these two rules–and many, many sites do fail one or both–and you’ll see a “Should Fix” message letting you know that you should: Eliminate render-blocking JavaScript and CSS in above-the-fold content.

eliminate render-blocking javascript and css warning pagespeed insights
Eliminate render-blocking JavaScript and CSS in above-the-fold content

What does that actually mean?

When a browser loads a web page, JavaScript and CSS resources usually prevent the web page from being displayed until they are downloaded and processed by the browser. In some cases, this is a good thing. For example, render pure HTML before any CSS is downloaded and you’ll get a flash of unstyled content (FOUC) which is probably a worse experience for your users than waiting a few hundredths of a second longer for content to appear.

Some resources need to be downloaded and processed before displaying anything. However, many CSS and JavaScript resources are conditional–that is, only applied in specific cases–or are simply not needed to render above-the-fold content. To produce the fastest possible experience for your users, you should try to eliminate any render-blocking resources that aren’t required to display above-the-fold content.

I want to be clear on one point: it may too much effort or simply be impossible to remove all render-blocking resources. Doing so may even produce the dreaded FOUC (up) I mentioned just a minute ago. Just remember that it isn’t our goal to attain a perfect PageSpeed score. Instead, our goal is to deliver the best possible user experience, and that means a website that loads as fast as possible without flashing unstyled content.

In other words, use PageSpeed Insights to identify render-blocking files that you can try to eliminate, but let UX be your overruling guideline. You might also see this message appear in other speed test tools. For example, in GTmetrix it shows up as “Defer Parsing of JavaScript.”

How to Eliminate Render-Blocking JavaScript and CSS

There’s a plugin for that, right? Well, sure, but you need to understand what’s going on before you start plugging in plugins. Many plugins are highly configurable, and knowing how render-blocking resources are eliminated will help you work more effectively with the plugin of your choice.

Clear JS from the Critical Rendering Path

First, let’s talk JavaScript. The basic idea is to move unnecessary JavaScript and jQuery resources out of the critical rendering path. This is typically done by adding either the defer or the async attribute to the script HTML elements that call JavaScript resources.

The defer and async attributes are not created equal, and the difference can be important to understand.

  • The async attribute tells the browser to start downloading the resource right away without slowing down HTML parsing. Once the resource is available, HTML parsing is paused so the resource can be loaded.
  • The defer attribute tells the browser to hold off on downloading the resource until HTML parsing is complete. Once the browser has finished with the HTML it will then download and render all deferred scripts in the order in which they appear in the document.

The big difference between the two is that defer ensures that scripts are downloaded and applied to the webpage in the order they appear in the HTML document, while async does not. The result is that if async is used on all JavaScript resources it can often break resources that are dependent on resources that appear earlier in the document. The most common problem async produces is broken jQuery resources that try to load before jquery.js has been added to the document.

Optimize Delivery of CSS Resources

Render blocking CSS can also be difficult if not impossible to entirely eliminate. The ideal arrangement is to:

  • Identify the styles that are required to render above-the-fold content and deliver those styles inline with the HTML.
  • Use the media attribute on the link elements that pull in CSS files to identify CSS resources that are conditional, that is, only needed for specific devices or situations.
  • Remaining CSS resources should be loaded asynchronously, a move that is typically done by adding them with deferred or asynchronous JavaScript.To be honest, we’re really getting in over our heads here, aren’t we? This is definitely front-end engineer territory. Which is great if you’re are a front-end engineer, but most of us aren’t. The good news is that this is an article about WordPress, and you can eliminate or at least significantly reduce the number of render-blocking JS and CSS resources affecting your site with the right plugin(s).

Plugins to Reduce Render-Blocking JavaScript and CSS

In preparation for this article, I worked my way through about a dozen popular WordPress plugins designed to reduce and eliminate render-blocking JavaScript and CSS resources and settled on five that produced a measurable reduction.

I should also mention that I did not use any caching plugins during this process. My test site was set up on a Kinsta plan which comes with built-in caching at the server level. If you aren’t a Kinsta customer, setting up a good caching plugin will further improve your site’s performance.

However, before getting to the plugins, we need a benchmark score. What I’ve done is set up a simple test site on Kinsta and installed a popular, free, jQuery-loving theme from WordPress.org: Sydney. Without doing anything else, here’s where we stand.

screenshot of pagespeed test without any plugins

Not too bad, but there is certainly room for improvement. There are two JavaScript and five CSS resources in a render-blocking position.

One other test we will use as benchmark is the Pingdom Website Speed Test. In particular, we want to take note of the number of requests required to load the webpage and see how that number changes with different plugins activated. Each additional request means another roundtrip to the server, so many plugins will combine CSS and JavaScript resources into fewer files to speed up website performance.

Since my test site is hosted on Kinsta, the site is blazing fast right out of the gate and required 24 requests to load the homepage.

screenshot of pingdom test with no plugins

Let’s see how we can improve on that performance by trying out a few plugins.

Speed Booster Pack

First up is Speed Booster Pack. This plugin is active on over 40,000 WordPress sites and gets a 3.6 out of 5-star rating at WordPress.org.

speed booster pack plugin

The plugin’s settings are found at Settings > Speed Booster Pack and the menu is reasonably simple while simultaneously offering quite a few configuration options.

The general options menu can Move scripts to the footer and Defer parsing of javascript files. In combination, these two options should remove render-blocking JavaScript entirely. Another menu titled Still need more speed? allows for the loading of CSS asynchronously. While this should have eliminated all rendering-blocking CSS, enabling this option produced the dreaded FOUC, so I did not leave this option enabled.

With the plugin configured, here’s how the site performed at PageSpeed Insights.

screenshot of pagespeed test with speed booster plugin

As anticipated, there are no render-blocking JavaScript resources left. However, since asynchronous CSS loading produced a FOUC and has to be left disabled, all five CSS resources are still blocking above-the-fold content.

screenshot of pingdom test with speed booster plugin

Curiously, the number of requests actually increased. While there was nothing to suggest the number should have decreased, increasing the number of requests is a surprise. The overall performance grade did improve a little, so I won’t call Speed Booster Pack a bust. However, there are more effective options available.

JCH Optimize

Next, let’s take a look at JCH Optimize. While the plugin has fewer active installs than Speed Booster Pack, it boasts an impressive 4.6 stars out of 5 rating.

JCH Optimize plugin

This plugin combines and minifies JavaScript and CSS, and along with many other features, is designed to speed up page loading. While eliminating render-blocking resources isn’t specifically mentioned anywhere, the combination of JavaScript and CSS files should mean that there are fewer resources required to load the page and fewer JS and CSS resources in a render-blocking position.

The plugin adds a settings menu at Settings > JCH Optimize. The settings menu has several pages with many different configuration options. To make things relatively simple I selected the Average automatic settings in the Basic Options menu.

The results were a little puzzling.

screenshot of pagespeed test with jch plugin

All JavaScript resources have been combined, which means only one JS resource is blocking the rendering of above-the-fold content. So far, so good. The CSS results are where we get into a bit of a head-scratcher. There are still five CSS resources in a render-blocking position. It looks like the plugin has combined and minified the contents of CSS files. However, font files have been excluded, and JCH has loaded three different CSS files rather than combining all three into a single CSS file.

That’s not what I expected to see. Let’s see what Pingdom’s Website Speed Test thinks of the changes.

screenshot of pingdom test with jch plugin

As anticipated, the number of requests has been reduced by one since two JavaScript resources have been combined. Other than that, the test shows performance that is virtually unchanged.

I expected a more measurable improvement from JCH. I expected all CSS files would be combined and there would be only two render-blocking resources left: one combined JavaScript file and one combined CSS file. I’m not sure why that didn’t happen. A premium version of JCH Optimize is available. So it’s possible that some of the advanced features would make it possible to further combine CSS files and reduce the number of render-blocking resources.

As things stand, JCH Optimize is not very helpful for optimizing this particular test site.

Autoptimize

With over 300,000 active installs and a 4.7 out of 5-star rating, Autoptimize is one of the most popular speed-optimizing plugins in the WordPress plugin directory. It also earns strong marks right off the bat thanks to the plugin author’s charitable and generous attitude.

autoptimize plugin

This plugin is designed to be simple to use and it lives up to that promise. Whereas many of the other options I looked at had very complex menus, Autoptimize is very simple. All I did was go to Strong > Autoptimize and select the three primary checkbox options displayed on that page.

autoptimize settings

Here’s how my test site performed at PageSpeed Insights after that simple 30-seconds-or-faster optimization.

screenshot of pagespeed test with autoptimize plugin

We’ve managed to reduce the number of render-blocking resources from a total of seven to four. Very good. Now to see how the number of requests has changed.

screenshot of pingdom test with autoptimize plugin

The total number of requests has gone down considerably from 24 to 17, and the performance grade has jumped to a very impressive 92. It looks like Autoptimize is popular for a very good reason. I should mention that Kinsta has noticed a trend of Autoptimize incompatibility with some sites that inline custom CSS in header.php. For example, if you have custom CSS coded into your theme’s header.php file take extra caution if you try out Autoptimize.

Async Javascript

Next on the list is Async Javascript. It isn’t tremendously popular, with just 4,000 active installs, but it has a very strong rating: 4.4 out of 5 stars. This is another dead-simple plugin. Just install and active it. Go to the Async Javascript option added to the Admin menu. Select the checkbox next to Enable Async JavaScript. Select the radio button for either the Defer or Async method. Then save the changes and see how your site performs.

In the case of my test site, async ended up loading some jQuery files before jquery.js which ended up breaking the site. So I went with the defer method. With those options selected, here’s how the tests went. First up, PageSpeed Insights.

screenshot of pagespeed test with async plugin

As anticipated, all JavaScript has been cleared out of the way, but the CSS hasn’t been touched. This is fine because this plugin is designed to address just JavaScript.

screenshot of pingdom test with async js plugin

The site performance on Pingdom’s Website Speed Test was pretty much unchanged with the plugin installed. Once again, this just confirms that this plugin does exactly what it says it will do: eliminate render-blocking JavaScript.

Combining Async JS and Autoptimize

The Async Javascript menu draws attention to the fact that it is designed to play nice with Autoptimize. Since I already had Autoptimize installed I gave that a try. After activating Autoptimize a new checkbox appeared in the Async Javascript settings menu to Enable Autoptimize Support. With that checkbox enabled, here’s how the site performed.

screenshot of pagespeed test with async js and autoptimize plugins

Excellent. With both plugins set up, we’ve managed to trim the total number of render-blocking resources down to just three CSS resources. How have we affected the number of requests?

screenshot of pingdom test with async js and autoptimize plugins

The site is blazing fast and only sends 17 requests.

Considered on its own, I’m not a huge fan of Async Javascript. It dedicates more space in the settings menu to advertising the premium version of the plugin than to the plugin settings. It adds a primary item to the Admin menu rather than adding it as a submenu item in the Settings menu where it really belongs. It misspells JavaScript by writing it Javascript. Ok, I admit that last gripe is trivial, but if the P in WordPress matters, then the S in JavaScript does too.

Update: The author of the plugin addressed these concerns after our post was published by reducing the size of the advertisement, moving the location of the plugin in the Admin menu, and even fixing the spelling of JavaScript. Color us impressed. Regardless of my thoughts about Async Javascript on its own, when paired with Autoptimize it does a great job of completely eliminating render-blocking JavaScript and trimming down the amount of render-blocking CSS.

Hummingbird

The last plugin I tested was Hummingbird by WPMU DEV. This is a premium plugin that I use on some of my own websites. There is no free version of the plugin available, which means it’s starting with one strike against it. However, it provided the most significant reduction in render-blocking resources, so it bears mentioning.

Hummingbird plugin

Hummingbird is a complex plugin, but also fairly user-friendly considering how much it offers. To move render-blocking resources go to Hummingbird > Minification and select Check Files. From the resulting screen you can select CSS and JavaScript files to move to the page footer or header, as well as files to combine and minify.

I combined and minified all files and moved them all to the footer with two exceptions: the theme’s primary style.css file and jquery.js. I found that both of those files must appear in their original location to avoid breaking the site or producing a FOUC. With those settings, here’s how the site performed in PageSpeed Insights.

screenshot of pagespeed test with hummingbird plugin

As expected, we’re down to just two render-blocking resources: style.css and jquery.js. Great. Let’s see what Pingdom can tell us.

screenshot of pingdom test with hummingbird plugin

While the overall performance grade isn’t as high as it was with Autoptimize, we have managed to trim the total number of requests to the lowest value we’ve seen so far: 16.

Async JS Works Well with Hummingbird

While things are looking really good, it occurs to me that Async Javascript might help us move jquery.js without breaking anything. After activating Async Javascript and rerunning PageSpeed Insights, I see we have almost completely eliminated all render-blocking resources.

eliminate render-blocking JavaScript

All that is left standing in the way is style.css. The last step to allow us to completely eliminate all render-blocking resources would be to inline style.css. However, we’ve managed to go from seeing a Should Fix message to a Consider Fixing message in PageSpeed Insights. I’m going to defer to Google’s definition of when to worry about a Consider Fixing message and say that what we’ve accomplished so far is a resounding success.

Conclusion

Not all plugins that claim to address and eliminate render-blocking JavaScript and CSS issues are created equal. Autoptimize used in combination with Async Javascript is the best free option I found for my test site. However, using the premium plugin Hummingbird along with Async Javascript produced results that finally satisfied PageSpeed Insights.

This article is far from exhaustive, and there are a lot of additional plugins you can use to address render-blocking resources. What plugins do you use and recommend to remove render-blocking JavaScript and CSS?