Speed up your Gatsby site with 1 line of code 🤯
Make your site friendlier and faster by reducing Javascript with a simple trick 🐱👤
TL;DR:
Gatsby relies heavily on Javascript through the dependence on React and the addition of a router and other logic to its runtime.
Hence, one could argue it's quite bloated for simple static sites, delivering tons of JS that users wouldn't otherwise need.
By changing the rendering engine from React to Preact we can reduce up to 100kb (unzipped) in bundle size, making our sites faster on mobile (runtime and loading) and more suited for SEO 🎉
And I finish with a bonus tip at the end, check it out 😉
The problem
Gatsby is great, and I mean it. It has allowed me to build complex sites with ease, such as Data Hackers, and unlock the creative freedom provided by building from scratch without the colossal work needed to build the basis for it, as there are many plugins and great guides out there. Also, it's just React with the added benefit of not having to care about webpack and the likes, so it's quite easy to get productive. In short, it has amazing DX, and it has brought me tons of joy since I started working with it in 2017.
What is not so amazing is its performance. Yes, I'm challenging their homepage slogan.
First, who even defines what "matters"?! Second, it likes to pride itself in being "blazing fast", that it provides speed by default, to which I agree to a bunch of cases, but not all of them. For a simplistic blog like the one you're reading, Gatsby actually hurts its performance. I'd have to do a terrible job to ship 70.9kb
of downloadable Javascript (219kb
uncompressed) on this very barebones page, and yet, that's what "fast in every way that matters" brings to the table.
I have a huge collection of thoughts on this and have been delaying a post on the shortcomings and threats of Gatsby for a while, but that will have to wait longer. To finish driving my point home, take a look at my Lighthouse score - measured on applied slow 4G for mobile - for the default Gatsby mode:
And keep in mind that the document itself is only 10.8kb, including styles, so a TTI of 2.8s for such a simple page is unacceptable (for me, at least 😜). If you want to see it for yourself, here's this version of the page.
The solution: reduce JS through Preact
Turns out Preact X just came out and, with it, came stability and reliability enough to ditch React for Preact as the rendering engine and benefit from the reduced JS. They say a picture is worth a 1000 words, so I'll give you two:
Now, that's better! Still a bit disheartening considering the simplicity of the page (which you can find here) and the fact that a few months ago this result was considerably better. As Lighthouse is changing its metrics and weight attributes over time (see the weights for V2 and compare them to the weights for V3), seemingly putting more emphasis on aspects that are highly affected by JS heavy set-ups, I expect Gatsby sites to perform worse and worse over time.
Anyway, it's still a good gain that becomes more expressive on bigger sites, and it comes at no cost / collateral, so switching to Preact is an obvious choice. I'm not sure if you'd hit incompatibilities on big apps that make use of other libraries such as Apollo, etc., but in my experience I haven't seen a single site with a problem so far. And to do it, the process is super straightforward and simple (alternatively, you can follow the plugin's official docs)!
npm i gatsby-plugin-preact preact
And then, in your gatsby-config.js
:
/* ... */ plugins: [/* ... */ `gatsby-plugin-preact`];
There you go! 1 npm install
and 1 line of code later, and you've saved 45.2% of uncompressed JS (43.02% for of the download size) 🎉🎉
Do yourself, and the internet / users / planet, a favor and do that for every Gatsby site you ever make! Heck, you can even bake it into your default base theme / starter, easy peasy!
Bonus tip: remove ALL Javascript 😈
Now, if you're building a simple website / blog that doesn't benefit from the SPA aspects of Gatsby and doesn't use any dynamic features of React, like my blog and many others I've seen out there, you don't need to cope with the tons of JS nor ditch Gatsby's data layer and templating niceties... you can remove all Javascript from your site!
This one is obviously not for every situation, but can make absolute sense if the average user of the site is not going to navigate to tens of pages and always come back, case in which having Gatsby's caching and service worker capabilities would be great. However, I'm more than happy to do this tradeoff on my own blog, and here are the results:
They speak to themselves, but they could be even better if the gatsby-plugin-no-javascript
- which I used to remove JS from the site - also removed the page-data.json
file, which increases my payload by 70,2% for no reason, as it only makes sense in the context of hydrating the app.
This is achieved with a simple yarn add gatsby-plugin-no-javascript
and adding the following to your gatsby-config.js
:
/* ... */ plugins: [/* ... */ `gatsby-plugin-no-javascript`];
⚠ Note: plugins related to your hosting provider - specifically, I ran into it with Netlify - can add some specific headers to you requests that point to JS files. Make sure to delete them to avoid this behavior 😉
In conclusion, Users will now save more of their bandwidth, load your site faster and feel less the effects of JS bloat (high input delay, janky scrolling, etc.). As web devs, we must be more and more vigilant to the impacts of our choices for businesses and users. Serving unnecessary JS might be comfortable for us, but it's bad for everyone, even the planet (think about the bandwidth, and consequent electric energy, being wasted on the internet!). We can't blind our sights to this in name of UX!