My PageSpeed Score Journey

TL;DR – Faster pages make everyone happy

This is my journey of how I achieved a perfect PageSpeed score.

Firstly, besides writing here on Dividend Derek, I created and run Custom Stock Alerts (CSA).  Being in the IT field, it’s important to continue working on my skill set.  CSA was the perfect project for me to try out some new technologies.  It’s hosted on Amazon Web Services (AWS) and I use a multitude of their services.  I honestly can’t speak highly enough of my experience setting everything up and the documentation available when I needed help (which is still often).

After launching CSA, I started researching how to make my site more visible, how to appear better on Google for SEO, things of that nature like any small business would.  I came across PageSpeed Insights and ran my initial test.  It wasn’t terrible, it wasn’t great, I think my initial PageSpeed score was in the 60s.

A high PageSpeed score is important for a few reasons, users won’t wait around on a poor performing site and Google understands this.  They won’t say just how much, but it appears to play a role in how high you rank on organic searches.  Also, to reiterate, being in IT it was something I also wanted to do to learn new things.

Initial Setup

The first trick was getting mod_pagespeed installed on my web server.  In a nutshell, the mod will do things like inline CSS, javascript, minify files, a lot of web tweaks plus a multitude of other things.  The mod is compatible with Apache and Nginx, I personally have Apache setup.  Once I had it installed and confirmed it was working.  Reran the test and my PageSpeed score only jumped to about 70.  Not the complete slam dunk I was hoping for.

Early pagespeed score

This screenshot was taken after a few of the initial low hanging fruit tweaks Google suggested.  One of the nice things, not shown there, is that Google will resize bloated images and let you download them which is exactly what I did.

The two biggest issues I had were with “Leverage Browser Caching” and “Eliminate render-blocking javascript and CSS in above-the-fold content”.

Leverage Browser Caching

There were a few complaints here, my external resources either had no cache expiration set or the expiration was too short.  To remediate all of these issues I first moved all of my static content to AWS CloudFront.  It’s a CDN that has my content at edge locations around the world.  I uploaded all of my content to my S3 bucket and set the following header:

“Cache-Control: max-age=31536000, public”

That alone fixed all of my browser caching issues after I first moved all external resources into my own CDN.  I even moved things like Bootstrap into S3, they were one of the offenders with a short expiration.  That whole exercise did take some time to upload all my content, repoint all of my URLs throughout CSA to Cloudfront, deal with permission issues.  I believe that the PageSpeed score in the image above was once I fixed all of the caching issues, that only left eliminating render-blocking content.

Eliminate render-blocking javascript and CSS in above-the-fold content

Just to begin, this is where I spent the majority of my time.  This was by far the summit of Everest in this journey.  So first – the issue it is describing is how in typical HTML code, the browser will stop and fetch each script and stylesheet before rendering the page.  That causes initial slowness as the page will wait for external resources to be downloaded.  What Google wants to see is that you can render your HTML and then as resources are downloaded they will be added.  Just for reference, above-the-fold content refers to what a browser will show without having to scroll, whether on your desktop or mobile device.

Fetch Inject

After much Googling on the topic, I found this library called fetchInject.  What this allows you to do is do asynchronous script and stylesheet imports.  It handles all the backend work, you just need to get the dependencies right.  Getting the dependencies right was another one of my big headaches.  You can nest fetchInject calls so that resources will be ready before the preceding one tries to execute – this can help prevent errors like “$ being undefined” if you are using jQuery.

fetchInject([
  https://npmcdn.com/bootstrap@4.0.0-alpha.5/dist/js/bootstrap.min.js
], fetchInject([
  https://cdn.jsdelivr.net/jquery/3.1.1/jquery.slim.min.js,
  https://npmcdn.com/tether@1.2.4/dist/js/tether.min.js
]))

 

That was the example code given, you can see how you can nest calls so that jquery and tether need to be loaded before trying to use the boostrap script.  The next issue is that only modern browsers can leverage this, sorry IE.  But – never fear – there is fallback code:

(function () {
  if (window.fetch) return;
  document.write(<script src=”/js/bootstrap.min.js”><\/script>);
  document.write(<script src=”/js/jquery.slim.min.jss”><\/script>);
  document.write(<script src=”/js/tether.min.js”><\/script>);
})()

 

For browsers that don’t support fetch, we insert the typical script tags (works for stylesheets also).  The issue that cropped up in IE is that the fetch script itself uses arrow functions (=>) that aren’t supported in IE at all, so it appears as a syntax error and then halts further code execution.  After another round of Googling I found Babel, this allowed me to take the fetchInject library and have it rewritten to something that also browsers support.  Now there is some progress!  At that point I could see my super fast page loads in Chrome with IE fallback support.

After making all of my code changes, tested them locally, testing them on my beta site and finally publishing to production Custom Stock Alerts, my PageSpeed score jumped up to 91.  How disappointing!  I had 100 score in beta – what happened?

Prioritize Visible Content

So my last suggestion was to “prioritize visible content”.  Remember that “above-the-fold” I referenced earlier?  This tells me, don’t cart along HTML that isn’t being used, rather defer it to “below-the-fold”.  Some of my modal boxes that I use throughout the system were meshed in with my navbar and header code.  This was a fairly quick fix, I moved that code to my footer.  Tested everything locally, tested in beta and finally pushed it out to production.  I then ran the test once more…

Perfect PageSpeed Score

Conclusion

I finally got my perfect 100 PageSpeed score! It took many, many hours of Googling and trial and error but I learned a great deal in the process. While, in my opinion, performance was never terrible to begin with, this will only help more.  I hope this helps you in some way, feel free to comment or reach out to me.

Also please give Custom Stock Alerts a shot, it has a free trial, no credit card is needed.  If you enjoy this content, consider subscribing to alerts.  Most topics will be around dividends and income but I’ll have posts referencing Custom Stock Alerts also.

Leave a Comment