Building a highly performing blog using the jamstack

Follow me while I'll be diving into the details that made it possible to get a perfect score in Lighthouse, while having fun developing this website.

Soap traces

As I already mentioned in a previous post, after a long period of having my "web presence" scattered around different services, I decided to bring everything home building this website.

As a software engineer, a web developer and as someone who cares about privacy and security, the requirements were pretty well defined. First of all I had no intention whatsoever to use Wordpress or anything similar: zero maintenance and total control were the first two priorities.

The obvious direction in this case was to look into one of the Jamstack options. Given my background I could have picked any of the possible implementations but I wanted to use just HTML, CSS and Markdown as my foundation so after removing all the React based solutions my selection criteria was more about community support; that led me to choose among Jekyll, Hugo and Eleventy.

"With Jamstack, the entire front end is prebuilt into highly optimized static pages and assets during a build process. This process of pre-rendering results in sites which can be served directly from a CDN, reducing the cost, complexity and risk, of dynamic servers as critical infrastructure." -- Jamstack.org

After a relatively quick look into Jekyll and Hugo, I decided to opt for Eleventy. With Eleventy it was refreshingly super clear to me how to build something right away, just in a handful of minutes, whereas with Hugo and Jekyll I was almost immediately overwhelmed by all the things I could do with them but they looked just too complex for my use case.

The list

  • I started from scratch (remember? I wanted full control!) but I used one of the "starters" template for blogs as an inspiration: I copied, adapted, removed several things from it. I have chosen the "High performance blog" from Google, which in turn is based on the "Base blog" one
  • I use Nunjucks as my templates' engine, but Markdown for everything content related
  • I extended Markdown with markdown-it-attrs because I wanted to target some content using HTML classes (mostly for using util classes for images). Markdown purists may give me the side look for this, I know
  • I was tempted to go with Tailwind for my CSS–because we all love it– but ultimately I decided to fly solo. The layout and "design" requirement are so basic that I actually enjoyed going back to writing some media queries and refresh my positioning skills (the CSS are a mess, don't look at them now)
  • Speaking of CSS: this project was actually the first ever where I have used the li::marker pseudo-selector and the text-decoration-thickness property for anchors. Cool stuff
  • The font selection is always a pain in the neck; after much browsing in Google Font, I finally settled with Poppins and Roboto Slab. For privacy considerations, the fonts are served by myself, not by Google
  • the semantic of the HTML structure and the level of accessibility of the website is carefully hand-crafted (an art which is disappearing, imho). Although not perfect (I would like to use figure for my images), I consider myself quite happy with the result
  • The design was pretty much inspired by the first title I had in mind for the blog; the title changed (to just read my name) but the strong brutalist black/white design remained. There are only two nifty things about it: the alternate colors for box borders in home page (try thinking how to implement them) and that short custom animation when a post is loaded, which gives it a nice "snapping" hint

Putting it live

Once I was happy with everything and I finished porting all the content I had to choose how to actually put the website online. I store the whole website in a (private) github repository and I want to be able to deploy with one single command, or even automatically after a git push. Here again there are so many options.

  • One could just use Github pages: is a simple solution, can accommodate for more sophisticated use cases and of course you don't need to "manage a server"; the problem for me was that the repository where you publish from must be public and you only get one site per account. Pass
  • Another option is to use Netifly, which is a pretty common choice nowadays. They also coined the term "jamstack"
  • Cloudflare has a nice, free option with Cloudflare pages which also integrates github. It's also quite easy to provide "dynamic functionalities" to your static website using their "serverless edge functions", called Workers
  • There are really too many options to consider so I rather send you to a very recent article reviewing all the most common solutions out there

After considering the alternatives I ended up using my own server (a VPS with Vultr). I have it since years ago, I barely use it for anything, and I still pay for it so I guess for me it made sense to use it. I am also very comfortable with the command line and setting up servers, so no big deal.

I am also using my own server because I wanted to be sure that I could always have control over my HTTP headers (like removing Google FLoC support if you still use Chrome) and my HTTP logs; as soon as I can I want to either remove them or at least redact any information I don't need from them (like your own IP address).

As for the how I am actually deploying just by issuing git pus live main, this is just a matter of following another guide I wrote years ago. The guide's use case is admittedly more complex than what I need for this website, but if you are interested, you can really extrapolate all you need.

Comments, likes? Use this Twitter thread!

Thank you for reading and follow me on Twitter for more technicalities.


Written on April 25, 2021 by Claudio Cicali.