Reasons to Migrate away from GatsbyPublished on
Holding steady against the onslaught of Gatsby bloat and dependencies
Gatsby is a site generation framework. I recently was using it for one of my side projects, sff.life, a site dedicated to small form factor computing (eg: small computers). I decided to migrate away from Gatsby, as it is not a zero cost abstraction for static sites for two reasons:
- Way too many dependencies and releases
Before I give a bit more background and expand on these reasons, I still believe that in many situations, Gatsby benefits outweigh the costs. In this way, Gatsby isn’t “bad” insomuch as one (ie: me) should be privy to exploring the simplest solution first.
So since I already had working knowledge of Gatsby, I decided to use it for project for myself, documenting my journey through SFF. I had grand visions of allowing contributors who could help via a non-technical interface. It’s been awhile since I’ve written content for it, as life has gotten in the way until fall, when I plan to breathe life into it again. However, Gatsby has also gotten in the way.
Screenshot of sff.life below
Gatsby is not lying when it claims that it is blazing fast. It is fast.
But there is a lot of room for improvement.
When using Gatsby, requesting the article How to undervolt your ryzen cpu results in 18 network requests and a total of 504 kB of resources. As a comparison, requesting the article at the time of this post, only 6 requests are made with 143 kB of resources. That’s a 3x reduction in number of requests and data transfer – a marked improvement.
Here’s a couple of statements from the Gatsby team that I’d like to examine that illustrates their viewpoints on JS.
you would [lose] a lot of functionality like page prefetching and in-browser navigation, lazy image loading, etc.
For non-apps, I do not see the benefit to page prefetching and in-browser navigation. Visitors to a blog most likely arrived via a google search or a link and are interested in only that one page. Therefore priority number one should be loading the initial page as quick as possible so they can see the content. I do not understand why there would be a significant focus on prefetching and navigation – content is king, let’s focus on getting that in front of the user as fast as possible.
To address lazy loading images – I have good news, browsers natively can lazy load images without any JS as shown below
70% of all users’ browsers support lazy loading images. This percentage will only increase in time, and while 70% is not as comfortable as 90, 95, or 99%, when working with a side project, if a majority of your users can take advantage of an emerging standard then I’m happy to drop the JS.
The Gatsby team isn’t blind to natively supported lazy load images as they will also tack on
loading="lazy" (or is it via a plugin?) to the generated page.
I’m satisfied with how I’ve addressed their need for JS, and how it’s not as widely applicable as they imagine. Though, interestingly, it also sounds like Gatsby advertises that it is faster than any equivalent site: from the creator of Gatsby:
To do anything in Gatsby, a plethora of plugins are needed. Sff.life, as simple as it is (a point I can’t stress enough), needed 21 direct dependencies. These 21 dependencies explodes into a 21k line package-lock.json. A large lockfile seems unmanageable, as one of the recommendations for mitigating vulnerabilities introduced via lockfiles is to “Carefully review changes to lockfiles”, but that won’t be happening to a 21k line file that is for a side project.
Don’t get me wrong, I can appreciate a slim core with plenty of extensibility points; however, Gatsby takes it to the extreme. Less than 4% of the commits on the site are authored by me. I’ve made 40 commits and dependency updates are over 1000 commits. This is in the span of less than a year. That’s hard to stomach and makes me numb to dependency updates. I should be attentive, ensuring that nothing nefarious sneaks in or just keeping up with what’s new or bugs fixed, but I just can’t. Waking up to hundreds of emails about new dependencies prompted me to create a separate email folder that is essentially black holed and ignore github notifications.
Just take a look at the Gatsby Github page and see how many releases there are:
Yes over 13,000 releases. This is almost hard to fathom.
There’s a potential monetary cost to all these dependencies updates. Previously I’ve praised Netlify CMS + Gatsby combination, and one of these benefits is that whenever there was an update to the backing repo, Netlify would build and deploy the latest version. The issue is that when there are so many dependency updates, one quickly closes in on the max allowed build minutes on the free tier. I normally have no problem paying for rendered services, but this is not one of those times.
Maybe upselling builds is how GatsbyJS (the business) drives most of their revenue. But if it’s not already the case, it wouldn’t be a bad idea for Netlify (and maybe other CI / CD companies) to sponsor Gatsby. Make it seem that Gatsby should be used for every situation no matter how simple (a hobby project or personal blog) – then watch as the users are unable to cope with pace with dependencies updates and are forced onto paid plans.
Can we reduce the bloat and dependencies? If not then this would be a pretty somber post, but it turns out we can. While I will be recounting the solution I settled upon, keep in mind that any dedicated static site generator will probably be sufficient.
Without further ado, I replaced Gatsby with Hugo. You can view the pull request for in depth details on the change, but it was remarkably straightforward, mainly fixing file paths, and adding a custom shortcode so that images are lazy loaded and sized appropriately.
Some notes on why I chose Hugo:
Hugo is a single binary that can be downloaded and installed easily for any platform.
Hugo extended bundles a SASS compiler, so I could install sanitize.css via
npm and write SASS that references this dependency. I have hardly any experience with SASS, but the fact that SASS is included out of the box and can reference node_modules made me ditch postcss in a heartbeat. The new
package-lock.json file is now 13 lines.
Hugo has a built in image processing pipeline. I make good use of it to create an array of images at varying sizes so that users don’t have to waste data and time downloading a high fidelity image when a smaller one would suffice.
CI Build times have decreased as well. Here are some back of the envelope timings:
- old (gatsby): 120 seconds
- new (hugo): 30 seconds
Hopefully it’s a bit more clear where Gatsby doesn’t shine as bright. I routinely see articles spinning Gatsby as the panacea for all web sites, and I just wanted to add a dissenting view to the conversation. To me, there’s a time and place for Gatsby, but it’s not for those projects that desire minimal maintenance, cost, and bloat.