Achieving the perfect PageSpeed score

I had the opportunity to redesign the website of A Little Fire Scarecrow, and in the process I learned a bit about how to achieve the perfect PageSpeed score, without compromising on what we wanted the website to be.

Since the artist’s name is a phrase from The Wizard of Oz, there’s quite a bit of competing search results, and we wanted to see if a perfect score would move the website up.

The basics

I host the website on Netlify, and in my experience, their CDN ensures speedy response times. Netlify support Let’s Encrypt out of the box, and pages that use SSL get a small ranking boost1, so I was off to a good start.

Inlining styles and scripts

I split the stylesheet in two; one for inessential styles, and one for everything else. The former is placed at the bottom of the page, and the latter is placed at the top. If PageSpeed tells you that you are loading too much stuff before displaying above-the-fold content, this is one way to address that.

All styles and scripts are inlined into each page at build time, except when developing, because that breaks the live-reload mechanism of Hugo.

Lazy-loading images and fonts

I wrote a bit of javascript that uses document.querySelectorAll to find all images with a lazy-load class. Those images look something like <img class="lazy-load" src="data:image/gif;base64,R0lGO‚Ķ" data-src"actual-file.jpg">, where src is a data URI that embeds a tiny placeholder image, with the same aspect ratio. The script then loads the image specified in the data-src attribute using fetch(), and caches them keyed on URL. A downside of this is of course that images don’t show for visitors with JavaScript disabled; I’ve yet to implement a fix for that.

The Google Fonts stylesheet uses browser detection to serve different CSS to different browsers, so I couldn’t host a local copy. I chose to load this lazily using JavaScript as well.

Getting the final point

After implementing the above tricks, the website had a score of 99100. One point was ironically deducted for including Google Analytics. So I decided to host a local copy, that gets updated on every deploy to ensure it’s reasonably up to date. This is just done before the hugo command with curl https://www.google-analytics.com/analytics.js -o destination.

Results

At the time of writing, alittlefirescarecrow.com is the first result for “A Little Fire Scarecrow” on Google, Bing, Yahoo, and DuckDuckGo. I’m not a professional web developer, so I’m quite happy with this.

I was also surprised and impressed at how quickly the Google index updates. I could make an optimisation, check the score, then see the improved search placement minutes after deploying the changes.


  1. Google Webmaster Central Blog. HTTPS as a ranking signal ^

Published in programming, web

Copyright © 2017 Alva