Simon Pfeiffer
Posted on August 8, 2023
As web developers page speed and performance considerations are at the top of mind. They affect all important KPIs, starting with user experience and ultimately affecting how well your content performs on search platforms.
Today we are going to be talking about advantages of static websites, consisting of simple HTML, CSS and a Javascript server that serves this static content. That doesn't sound very sexy at first but bear with us for a second.
The fastest growing web development framework in recent years is arguably Next.js. The popularity is caused by a combination of easy to use (heads off to the people at Vercel!) and the fact that Next.js managed to solve some key concerns of serverside rendering frameworks like React. Next.js achieves this by pairing react with an intricate logic for serving static props - and on top it runs well on Serverless infrastructure, making infrastructure setup a no brainer (at least for simple use cases).
Now under the hood Next.js is still a react based framework and as such it’s the server and setup are not exactly lightweight. Don't get me wrong, it is very impressive how much faster Next.js can be compared to a standard React in many cases - but we want to argue today that for smaller / mostly static use cases, Next.js might be overkill and can easily be outperformed by a more simple setup: Static HTML, CSS & Express.js server. We call this back to the roots, because all mentioned web frameworks rely on these and build on top of them. At Codesphere we have recently been turning to this simple setup for a lot of use cases - originally not because of speed considerations but because stripping away all unneeded complexity it made us much faster in the marketing team.
When concerned with speed few things can beat a simple express.js server serving static html content. The main issue here is that most use cases are not simply serving static content. If your use case is purely static i.e. a landing page you should probably look no further. We have recently switched all our landing pages to this approach and can highly recommend it! It even makes things like a/b testing soo much easier 😎
If your use case is not as simple as serving a static landing page it might still be worth considering if it can't be turned into a static website with a few tricks.
Let’s take a look at an obvious example - a blog frontend is not static per se as you will keep adding or updating content regularly. Upon closer inspection you might concede though, that updates are not that frequent, maybe a few times a week, depending how active you are. In such a case it’s actually rather easy to turn to fully static pages, you will just need a way to automate replacing the static content regularly - more on that example in a bit.
Even for other cases it might be worth asking what portion of your content actually changes frequently and as a consequence if it might make sense to serve the static parts as such, simple html files, served via express.js and only adding dynamic pieces on top. You will be rewarded with much faster pages in return.
Case Study - how we transformed our blog to a static frontend
So far our codesphere blog is part of our monolithic website, which uses quite a few frameworks and databases to ultimately pull and serve the content from our ghost.io backend.
It includes middleware for caching, webpack for compiling the files and typescript for all the server operations. As part of our move towards more simple frameworks, that the marketing team can handle and adjust without Dev team support we are also redoing our website, and therefore building a standalone version of our blog hosted inside of codesphere.
When turning a non static use case into a purely static website you basically have two potential approaches to handling updates to the underlying content. Either you periodically run code that pulls updates and replaces the static files with updated versions or you can attach a trigger to the event that caused the update in the first place. Which option you prefer might depend on how frequent you expect updates, how computationally expensive (in terms of resources) the static file generation is and more.
For our blog we expect updates a few times a week at most, currently we do not have comments, if we did we would probably add these dynamically on top. Also our CMS ghost.io provides built in triggers (webhooks) whenever content changes.
Now the webhook offers somewhat limited functionality - therefore we did need to implement a small server for handling the requests and forwarding them to GitHub with proper authentication. In GitHub we have repository which get's the updates as a commit and the configured GitHub action then takes the updates and triggers a deployment of the updated static html, css and javascript. The functionality we exploit here is Codesphere's preview deployment via GitHub actions - just that we (mis^)use it for the actual production deployment of our headless static blog frontend. We are already working on building a public Codesphere API, this will make it even more flexible.
If running (and paying) two separate workspaces is a concern for you, you could also configure the webhook listening & committing the changes to the repo into one application, we decided against that because we don't want to occupy our static server with anything but serving static content (for maximum performance) - but you could also counter this by restricting updates to run nightly only, when traffic is low anyways.
Alright this leaves us to finish adding some additional functionality to our headless blog frontend but we managed to fit a non static case into a lightweight static infrastructure. The whole thing took around one day to setup, it would be less if you were not building an entire headless frontend from scratch and instead go with an existing html template.
Performance tests
First of all I'd like to point out that the static regeneration only runs a couple of seconds for our full set of 160+ blog posts, if the number increases greatly it would be somewhat easy to restrict regenerated files to those that changed. Also you might be concerned that the workflow with multiple workspaces and GitHub action in the middle takes long, it doesn't! From triggering a change to the update being live on the deployed frontend takes 1-2 minutes only.
Now to the actual static website, performs like a champ! We are not quite ready to share the URL yet as we are still tweaking the design but stay tuned, revisiting our blog in the future might just blow your mind 😎
Happy coding!
Posted on August 8, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.