For those of you who know us, you know we’ve been pro Jamstack from day one. And while our website was a full-blooded Jamstack build (Gatsby + Contentful + Netlify) we have had minor, hmm, glitches which, in all honesty, damaged the advocacy we were so into.
I’m talking about the website performance of course. Better performance together with higher security, easier scaling, and cheaper hosting, is one of the top-selling points for Jamstack, right?
Guess what, we fluked in that area.
In the spirit of radical transparency we value in our business approach, take a look at our previous Lighthouse scores for our home page:
- First Contentful Paint1.5 s
- First Meaningful Paint1.5 s
- Speed Index4.7 s
- First CPU Idle5.7 s
- Time to Interactive13.9 s
- Max Potential First Input Delay660 ms
And for one of our most popular blog pages:
- First Contentful Paint1.6 s
- First Meaningful Paint4.5 s
- Speed Index5.7 s
- First CPU Idle14.1 s
- Time to Interactive14.7 s
- Max Potential First Input Delay880 ms
Not a good job I'd say.
Not only that we needed to improve website performance but we also needed to improve overall site architecture. On the business side of things, we need to support the brand trust and credibility we’ve built. To create a seamless experience for new and old users, regardless of which device they are using, that would incite them to engage with our content and get in touch with us.
Join Bejamas newsletter
Get our EXCLUSIVE web development case studies in your mailbox!
Web dev time, or the lack of it, was the main issue. Now, we could blame it on amazing projects we’ve worked on (some of them are featured here) but the truth of the matter is that we wanted it to be the brainchild of all of us at Bejamas. Getting everyone in a remote team to participate with ideas and suggestions was as hard as it was deciding which ideas and suggestions would become a part of the project.
Thankfully, we had our CTO Thom Krupa acting out as a lead dev in this project and who better to explain the ups and downs, the whys and hows of this build than Thom. So, instead of our usual case study format let’s hear the man out.
Why change Thom? What did we do wrong before and why?
The previous website was created in May 2018 I think. We built it really fast using a premium theme from a marketplace we liked. It took us about 2 weeks to ship an MVP and validate our business idea.
Even though the website has been working well, we had Gatsby v1 running it and a lot of outdated dependencies and dead code. On top of that, we’ve been struggling with occasional performance issues. And it just didn’t feel right. We’ve been creating really fast and beautiful websites for our clients and it seemed odd bragging with ‘performance’ while having your own website falling short in the same area. Especially with performance being one of the selling points for the Jamstack.
What was the previous stack we used? What problems did we have with it?
Gatsby as static site generator, Contentful as headless CMS for our blog, and Netlify for hosting and deployment. Nothing wrong with the stack really. We’ve used it on a few more projects. But, as I mentioned already, we were using Gatsby v1.x version and it needed an upgrade to the latest version. Gatsby is moving fast, fixes bugs, and improves performance on a daily basis and with each day we were more and more behind.
We were using too many 3rd-party scripts we didn’t really need, JS-heavy animations, etc. All of these issues influenced not only performance but also UX and we needed to change that.
What is the tech under the Bejamas hub today?
Overall Gatsby, Forestry as headless CMS to manage our content and Vercel for smooth deploying. On top of that, we used Cloudflare Workers to cache static third-party scripts. In case you are not familiar with it, it rewrites the HTML to replace the third-party script URLs with URLs that are proxied through the origin and appends a content hash to the URL.
The goal was to create as the light of a website as possible, but still, have a web-app experience like instant route transition. In the future, we would like to add more reactive components. That’s why we bet on (p)react from the very beginning. Thanks to SSR offered by Gatsby out of the box, our website works perfectly even with JS disabled.
Many websites use Gatsby today, but not all of them have good benchmark results. How did we achieve ours?
Not sure how many are familiar with it but the overall idea is to set goals early so that you can better balance performance without harming functionality and/or user experience.
Utilizing performance budgets in this build helped us to keep good performance through the whole process. We wanted to reduce everything we could - fonts, images, sections, 3rd-party scripts and keep just the essence but still, have a unique feeling of the brand.
We also used Linaria for CSS as it creates almost 0 bytes of runtime JS, but provides a good CSS-in-JS experience. It comes with some downsides, but we’ve handled those easily.
To save a few kilobytes more of JS we switched from React to PreactX. It’s not released as a stable version yet but has been working pretty stable for us.
We cut an additional 5kb by using the react-head. It may not be as advanced as a popular react-helmet but it has everything we need to manage SEO-related head tags. In case you want to use it in one of your projects we’ve created gatsby-plugin-react-head to make it easier for you.
Finally, we decided to use Vercel and Cloudflare CDN this time.
There are a couple of reasons as to why but one stood out: Vercel + Cloudflare supports Brotli compression. Now, we tested both gzip and Brotli compression, and in our case total transferred size of files compressed with Brotli is approximately 14% smaller than gzip. Since in this project we’ve been very radical about optimization Brotli was a clear winner.
Why the change of headless CMS?
We changed headless CMS from Contentful to Forestry. Over time, and a lot of projects, we had a chance to work with several different API and Git-based CMSs. For a project like this, where we did not have to create hundreds of posts and rebuild the website every 2 seconds, Git-based CMS (Forestry) is a far better option.
Personally, I love that I can edit content in Visual Studio Code and push changes through git. At the same time, we have a nice CMS editor for our marketing team.
Speaking of which, what are your impressions of Forestry UI?
Well, it is a fairly simple and clean CMS with an intuitive interface. Love the fact you have it all on one screen i.e. left panel is for your contents' front matter and the right panel is for the markdown editor that works just like any other WYSIWYG editor (I love the keyboard shortcuts for easy formatting info that shows with the toolbar).
Preview is a nice feature, so thank you for enabling it.
The best thing about Forestry is how easy it was to configure markdown files with custom fields (we added schema tags field, title and meta title field, etc.) or at least it seemed easy to me. Or we simply did a good job at it.
Forestry as Headless CMS
Before we continue with the interview let me share a couple of things about Forestry. First of all, Forestry is Git-based CMS which means it doesn’t have an API and a database. It is a layer on top of Git and it's interacting directly with the files in the repository. Every action that happens in the CMS like editing, creating, and deleting is an action taken as part of the git workflow.
Second, setting up Forestry is fairly simple. Once you sign up and before choosing your repository, choose your static site generator. Forestry supports many SSGs and provides default settings for Jekyll, Hugo, VuePress, and Gatsby. Finally, set your git provider which can be GitHub, BitBucket, GitLab, and Azure DevOps, and you are set.
OK. Now back to the interview.
The biggest challenge you had while doing this project and how did you overcome it?
Finding a good and low runtime cost CSS-in-JS solution was challenging. We’ve been using styled-components in most of our projects so far and we really love it. The runtime cost of v5 is around 12kb min + gzip. I was curious if we can get rid of it. After some research, I discovered linaria and astroturf. Both claim to be “Zero runtime CSS-in-JS” libraries. We made a bet on linaria and so far it does its job.
Was there anything about the implementation/results that surprised you?
I’m really stunned by how Gatsby improved DX and built an amazing community over time. V1 had a lot of bugs, weird behaviors, and a lack of stability. V2 brings pleasure to the development process.
Finally, your general opinion of the 'stack' combo that you were using in this particular project? The good and the bad sides?
I do like the stack we picked. I think there are still some opportunities to improve performance, especially on the gatsby-internal level. I’m watching closely work related to enabling modern builds.
Let’s have a look at the Lighthouse scores once more:
- First Contentful Paint1.1 s
- First Meaningful Paint1.1 s
- Speed Index1.6 s
- First CPU Idle2.6 s
- Time to Interactive2.6 s
- Max Potential First Input Delay180 ms
Not too shabby if I may say so. The thing is, those scores are just the tip of the iceberg as far as we are concerned. Because web development is not just about speed and performance isn’t it?
Being a web dev shop over time I’d say we’ve learned pretty damn well how to balance performance, design, clients' wishes, developer’s experience, and audience expectations. So sometimes, while speed is important, so too can be the need for video and fancy animations which can trump performance numbers but raise conversions. Other times better UX, content, and visitors flow or branding is under the spotlight.
Finding the sweet spot for each client is the real art. Think we’ve nailed it, again!
Wonder if we can help you out? Let’s get in touch!
CLICK HERE to schedule a 1-on-1 talk and let us show you what we can do for you and your business.