Page Speed Optimization

The most beautiful, well-designed, responsive, SEO perfect web page can be rendered meaningless by slow load times. Today’s web users are used to pages that open in the blink of an eye, with little patience for blank screens and spinning loading GIFs. This problem cropped up on a page we work on- a quick Lighthouse audit revealed a score of 52- mainly for the following reasons:

  • Unused CSS being loaded
  • Large amounts of 3rd party JS
  • Off screen images being loaded in the beginning

So let’s break down why page speed is important for SEO, and the solutions we found to each of these problems (and more).

The Importance of Page Speed

The fact that Google has provided developers with a PageSpeed Insights Tool should be enough to signify that it takes the loading times seriously when it comes to rankings. In 2018, they rolled out the “Speed Update”, confirming that they would use speed as a factor in mobile page rankings instead of just desktop searches. Another thing to consider- a site that lets the user hang on a blank white screen as it struggles to load will have higher bounce rates, which in turn will affect its ranking.


The bulk of our problem with CSS lied in the fact that the page was loading in much more than it needed. The page used two files (one for regular styles, one for responsiveness), which included rules for the entire site. Almost none of those rules were clearly labeled regarding where they were used in the site, so extracting only the necessary ones manually would be nearly impossible.

The solution was a PostCSS plugin called PurgeCSS. Given a CSS file and the pages you want to extract classes for, PurgeCSS generates an output file containing only the CSS it finds in said pages. It allowed us to whitelist certain classes (both by name and with regex), and was easy to implement in our gulpfile.js.

Normally, PurgeCSS requires the file names of anything that makes up the page it will be “purging”- layouts, partials, content, etc. In a complex setup where it might be easy to miss files (and time consuming to alter them for the next page), this is less than ideal. Instead, we decided to get the page’s content through a cURL request, pass the body on to PurgeCSS, and then piping the result for any other necessary processing.


Most Javascript related page speed problems can be solved with the use of preloading. Google has a thorough documentation of all the techniques, but the gist of it is that figuring out the priority of your resources and loading them accordingly can drastically improve your site’s performance.


The first step is to determine what exactly the scripts you include are used for- anything responsible for interactions that take place after the page has loaded (such as on-click events, smooth scrolling effects, etc.) can be safely deferred to after the HTML is done parsing. The file is loaded asynchronously, and only executed after HTML parsing. Placing such resources at the end of a file as opposed to the <head> is also recommended.

Preconnect and Async

Our site includes a handful of tracking scripts, and the amount of calls to third-party resources was affecting page speed. To speed things up we used rel=”preconnect” along with async to:

  1. Let the browser know our page intended to establish a connection to another domain
  2. Not pause HTML parsing while the script is being fetched

Images and Videos

Off-screen images can also lower page speed. The solution is image deferring- delaying the loading of images until they are visible on the screen. For our page, we used a simple, low size image as a placeholder to indicate that an image was supposed to be there, and then used one of various methods to switch the placeholder out with the actual image once it became visible.

The first and easiest to implement was the quru image-defer library. An image’s actual source is marked as data-defer-src, and the library does all the heavy lifting by switching the two to display the image only when it is in view. For images displayed through CSS (such as with the background-image property), however, a different strategy had to be employed. According to its documentation, IntersectionObserver “let[s] you know when an observed element enters or exits the browser’s viewport”. This can then be used as a trigger to know when to replace the placeholder. IE support requires a polyfill.

Youtube videos should not be overlooked, either, as the scripts required to embed one can impact page speed. Deferring is also the answer here. We decided to display a placeholder thumbnail and only create the iframe element in JS after the page finished loading.


While the aforementioned points will impact your page speed the most, there are a handful of smaller improvements that can also be made, such as:

  • Avoiding excessive DOM size
  • Using rel=”preconnect” for any Google Fonts
  • Setting the font-display property to swap to fix “Avoid invisible text while webfonts are loading“
  • Compressing images
  • Minifying all CSS and JS files

Useful Resources