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.

I am on BlueSky (@caludio.social).


Written on April 25, 2021 by Claudio Cicali.