NIKLAS ALMQVIST GAME DEVELOPER - WEB DESIGNER - APP DEVELOPER - FUNNY GUY

Increasing speed: How I finally scored 99 in PageSpeed Insights, and how GDPR helped me.

This is the first part of my journey to improve my website in any way I can, with the ultimate goal to perform better and better in the Google search ranks. As my first attempt, I decided to tackle one of the easiest culprits: the performance of the website. The performance is measured using PageSpeed Insights, and when I started my homepage was around 60-70 on mobile. Now, it’s 99. This is the story how I did it, what I learned, why I’m not at 100 and how on earth the mostly annoying law of GDPR could help me with that goal.

I am on a quest. Right now, if I Google my name (Niklas Almqvist), I’m on page 4. Or page 5, depending on who and where you are. I am not pleased with this, and have made it my goal to at least do everything in my power to improve my ranks. Whether or not I succeed, that’s for time to tell. This time, I focused on increasing the speed of my site, in order to score better on PageSpeed insights.

I started this task with a score of around 70.

Unfortunately I don’t have any photographic evidence of this, so you have to take my word for it. But when measuring mobile, my score went up and down around 70, but never climbed over 75. Sometimes it was even around 60. For a website created by a professional fullstack developer, that’s not very selling. And do be frank, it was pure laziness why I allowed that to go on for over a year. I didn’t have any interest in analysing it further. But as I stated above, I have recently received a burning desire to solve these issues.

And it turns out, it had a lot of issues. The tips and screams provided by the measuring website was plentiful, and often really helpful. It could be things like images that wasn’t loaded, scripts that didn’t need to be included at all and on, and on, and on. And when I started this task, I never could think that one of those warnings would be removed just by adhering to the GDPR law. It’s gonna be an interesting read, I promise!

The first issue – HTTP2

This was a really easy thing to fix. The website just wasn’t using the newer, faster protocol. It’s called HTTP2, and has been available for a while now, and the reason I haven’t upgraded it yet is that I didn’t know it existed until pretty recently. You see, my website is hosted on a VPS (virtual private server), so everything there is installed by me and only me. And I am not that good in handling infrastructure yet, and that is why I didn’t realise my NGINX-config lacked that code. It’s not even a code, you simply add http2 in one place. But I have been fortunate enough to learn a bit about infrastructure at my daytime job, so now I knew exactly what it was complaining about.

…And what is NGINX?

NGINX is the web server which receives requests from the internet and forwards it to the correct place in the server. You can specify the headers that you include with your response, the folder on your server where everything is situated, and of course, which protocol to use. I hadn’t specified anything, so it used HTTP1.

How did I add it?

I Googled a bit, and then I followed a tutorial/discussion of course! HTTP2 is only available for SSL-requests (secure requests using HTTPS), so it turns out you only have to add the word http2 at the end of your SSL listen statement. Incredibly easy!

listen 443 ssl http2;

Assets cache

Speaking of NGINX, another thing I missed while developing my own NGINX-config files were the assets cache. Essentially, assets like styles, scripts and images do not change that often, and therefore we can instruct the browsers to store it locally for a set amount of time before we need them to fetch it from the server again. This was a pretty easy thing too. After some Googling I ended up with the following code:

location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    	expires 365d;
    	add_header Vary Accept-Encoding;
    	access_log off;
}

I tried multiple values in expires, but the warning didn’t go away until it was set at a minimum of one year. Then a header is set to tell the browser it is allowed to cache these files, and the access log is turned off to make it run a tiny bit faster. All this means that for one year a browser does not have to retrieve our assets again.

Well what if I want to update my styles, do I have to wait a whole year?

No! Let me introduce you to the concept of Cache Busting. If we append something after our assets, such as a query parameter (styles.css?version=10), the browser will think it’s a new file and reload it again. I’m using WordPress for my site, so whenever I change my CSS or JavaScript, I change the version number in my styles.css, and then when my assets are enqueued it receives that version parameter stated above. Making that work in WordPress is as simple as adding wp_get_theme()->version as the last parameter of the wp_enqueue_style function.

wp_enqueue_style( 'style', get_template_directory_uri() . '/css/style.css', [], wp_get_theme()->version);

Leaving NGINX, let’s head to WordPress.

WordPress is a fantastic tool for managing websites. It’s easy to use, easy to customise and written in PHP which I really enjoy writing. But because WordPress is made for handling a lot of different pages, and it’s easy to customize, a lot of things gets sneaked in without you really knowing. One thing PageSpeed Insights complained a lot about is that I had a lot of styles and scripts which was added by WordPress and plugins, but never where used. So I removed them, and the warning went away.

Slow plugins

One of the main culprits on the WordPress-side was a plugin which measured traffic to the site. I measured it in the network tab of my developer console in Chrome, and one request that plugin made took over three seconds!?! Needless to say, that plugin went right down the trash. It wasn’t even really necessary, I was once again just too lazy. I didn’t feel like setup Google Analytics, so I opted for installing a plugin instead. This time I actually installed Google Analytics and smiled watching my PageSpeed meter increase.

Google fonts and preloading

Another thing it complained about was that it thought my Google Fonts loading was blocking the rendering. I just had a link which imported it in the header. But again, after some Googling I ended up on this nice page which had a really good example on how to solve this. So I implemented it with the code below, and the warning went away!

<!-- connect to domain of font files -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- optionally increase loading priority -->
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Poppins:ital,wght@0,100;0,400;0,500;0,700;1,400;1,500&display=swap">

<!-- async CSS -->
<link rel="stylesheet" media="print" onload="this.onload=null;this.removeAttribute('media');" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Poppins:ital,wght@0,100;0,400;0,500;0,700;1,400;1,500&display=swap">

<!-- no-JS fallback -->
<noscript>
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Poppins:ital,wght@0,100;0,400;0,500;0,700;1,400;1,500&display=swap">
</noscript>

Images

For some reason I had uploaded images as PNG’s when they clearly should be more optimised as JPG’s. Some which has to be PNG’s because of transparency I installed a plugin for which converted them into WebP’s. One thing I already added before was lazy loading. which essentially is that images load only soon before they are going to be visible.

Google Analytics and GDPR?

Now, as I stated above I threw the visitor statistics plugin miles away and instead installed Google Analytics, both because it was way more performant and had more functions, but also because the plugin wanted me to buy features which Google Analytics provides for free. But when I did this, a new warning was raised by PageSpeed Insights. It thought the GA code I added was unnecessary and thought I should remove it. But I don’t want to do that as I need to know how my visitors experience my website in order to improve it. That’s especially important for the quest I’m currently on.

GDPR and EU laws

While researching this, I encountered something I hadn’t really thought about before. The European Union has a few laws and directives concerning privacy and cookies. Essentially, cookies and tracking cannot be used until the user has given consent, and it has to be an active choice, not just a banner like before 2018 when GDPR was created. And guess what, Google Analytics uses cookies! So I am not allowed to include Google Analytics before the user has given consent. And PageSpeed Insights cannot give consent. Do you see where I’m going with this?

By creating a cookie consent form, which I, by law, am required to have, PageSpeed Insights do not complain any longer about that unused script. It’s a win!

Downside

Or it’s not a win. By requiring active consent to start tracking the user, we miss out on some users. It’s not the biggest loss, because users that do not navigate the site is not very interesting data points. But still, the statistics can be a bit misleading because of that.

But there’s hope! Google Analytics has an experimental feature called “Consent Mode” which is supposed to solve this exact problem. I am yet to research it closer and implement it, but it looks promising!

The results

PageSpeed Insights of https://niklasalmqvist.se - the diagnostics
The final PageSpeed Insights
PageSpeed Insights of https://niklasalmqvist.se - the diagnostics
No warnings left!

Where to go from here

Regarding the topics in this article, there are a few things I’d like to continue improving.

  1. Try and reach 100. I’ve done everything PageSpeed Insights told me I could do, and it got me almost to a 100. But not exactly. As we see in the screenshot above it still took a little while to load the page on a slow connection, so that is something that needs to be looked at. But for now, it’s enough from my perspective. Listed below are the next few steps I’m eventually going to try to receive the glorious 100 points.
    1. Try to put my assets behind a CDN. I got some experience in CloudFront, so I might test that.
    2. Try to improve the server speed. Maybe check if there is some cache extension for PHP which I miss?
    3. See if there are more settings in my WordPress cache plugin which I can tweak to cache even more stuff, or put it on a faster cache.
  2. Try out Google Analytics Consent Mode, see if I can track first time visits accurately but anonymously.

Conclusion

With pretty easy changes the score of the site increased heavily. And thanks to PageSpeed Insights it was really obvious where focus had to be put in order to improve it further. Of course, sometimes not everything was correct. For example, when it complained about my scripts it included jQuery. But I require jQuery for my other scripts to work. But by removing the other unused scripts, it was satisfied and happily ignored that I still had jQuery included.

If you feel like exploring the lightning fast speed of my website, go visit it here at niklasalmqvist.se! More blog posts like this will be added in the Thoughts section.