Improving Google PageSpeed Insights scores through JavaScript and CSS deferment in WordPress

In their quest to optimize all the things and please the gods of Google, a number of our clients have approached us in the past to inquire about improving their PageSpeed Insights scores. Sometimes, in varying levels of panic.

But first, it’s worth asking; do you need to improve your PageSpeed score? Are you sure?

Often, the answer isn’t so clear cut.

By all means: don’t ignore Google and SEO. Take care of the low-hanging fruit. Use a mobile responsive theme, install an SSL certificate and do whatever you can to make your website as fast as possible. Not just because Google says they want those things, but more importantly, because your real, human users want them too.

Beyond that, however, many businesses face the prospect of spending more money and time in pursuit of diminishing returns. In ranking for competitive search terms in a competitive market, a prizewinning PSI score for an otherwise competent website is pretty far down the list of things that will actually move the needle.

However, let’s assume that you would like to improve your PageSpeed Insights score. As with anything in WordPress, doing so may depend on many factors. Amongst them, your selection in:

  • Hosting. Choice in host is arguably the single most impactful step you can take in real-world speed. Factors include use of SSD (vs. slower HDD platter drives) use of PHP 7.2 or 7.3 (vs. heaven forbid, 5.x), opcache, HTTP/2, a stable infrastructure and plenty of other lesser-appreciated but still important optimizations. (I’m partial to Webster Park Digital but then again, I’m its co-founder.)
  • Theme. In particular, the “do everything” themes which are popular on marketplace sites like Envato tend to be bloated and grossly inefficient. (I use and swear by Beaver Builder, exclusively.)
  • Plugins. “Too many plugins” is an easy but misleading target; plugin quality is harder to assess but far more important. A single, bad actor can drag performance with inefficient code or database queries.
  • Images. Few things will tank your PSI scores like poorly optimized images. I love Imagify; it consistently provides the greatest reduction in files sizes with little to no loss in visual acuity. (Of course, your theme and plugins must also support responsive images too.)
  • Caching. By default, WordPress does not attach caching headers to things like image files or external JavaScript and CSS. Left to its own devices, WordPress will also perform resource-intensive regeneration of HTML content with each and every request; even if that content hasn’t changed since someone else last requested it. A great caching plugin (I prefer WP Rocket) solves both of these problems.

In many cases, it’s relatively easy to optimize all of the above. If your host sucks, switch hosts; if your theme sucks, switch themes. Install high-quality plugins from reputable sources and deactivate anything which isn’t in use. Activate Imagify and WP Rocket. And so on.

Often, however, once you’ve taken these steps, your WordPress website will persist in loading dozens — sometimes hundreds — of external resource files. This brings us to the topic of today’s post: how to safely defer the request of external JavaScript and CSS in your WordPress website.

What does “deferring” JavaScript or CSS mean?

When a user attempts to view a page on your website, a render-blocking request is simply one which prevents the browser from carrying on with its task of rendering the requested page to browser until that child resource has been loaded.

Most often, this takes the shape of external JavaScript/jQuery libraries and CSS stylesheets. A modern WordPress website might load several dozen resources on a single page; larger or poorly optimized websites might load hundreds.

Now on a fast computer, utilizing a fast internet connection, requesting a fast website from a fast host, all of this happens in little more than the blink of an eye. Render-blocking resources are far more consequential in suboptimal conditions — say, an underpowered mobile device on a slow network, making a request of a poorly optimized website on a resource-starved host.

Note that Google Page Speed Insights will complain of any render-blocking resource; it isn’t always possible to defer every request. (You cannot, for example, defer jQuery itself without breaking virtually any modern website.)

WP Rocket may help … sometimes

WP Rocket supports deferring JavaScript and CSS; unfortunately, it doesn’t [currently] allow you to take granular control over precisely which resources are deferred.

Which resources can be deferred?

Inlining resources

Of course, in order to get PageSpeed Insights to drop its complaint, you can simply inline any offending external CSS or JavaScript. Problem solved, right?

Not so fast. While this certainly may represent a viable approach in the case of mission-critical CSS or JavaScript, it simultaneously bypasses a browser’s capability to cache the script, thereby increasing the size of each and every page load.

How do I defer JavaScript?

How do I defer CSS?

Astonishingly, in the year 2019, there is no substantial, cross-browser support for deferring CSS. It involves a similar WordPress hook and a bit of JavaScript trickery.

How do I defer images?

To “defer” an image is not quite the same process; an image isn’t “render-blocking” per se in the same fashion that many JavaScript and CSS files are. However, insofar as multiple image files are often — by far — the largest bandwidth suck, it often makes sense to defer loading images which are safely offscreen, until the user is ready to view them.

Historically, this is known as “lazy loading” and is usually accomplished with JavaScript; my

WordPress recently introduced terrific support for responsive images; of course, it’s up to theme and plugin authors to utilize it.

Chris Aram

I'm a developer who specializes in whipping your technology into shape so that it makes your professional and personal life better.