Before I built this essay website, I’d built several iterations of it in different web technologies. It started with plain HTML in my first few weeks learning, and eventually moved to JavaScript frontend frameworks like Next.js. The previous version of this website was built in Next.js with hashicorp/next-mdx-remote, and its design is shown in Fig. 1.
It functioned well, looked nice, and had a command palette powered by timc1/kbar, but it had a problem: bloat. You can tell how large a website is by going to the devtools in your browser and clicking on the network tab, as shown in Fig. 2.
The network tab has a lot of visual noise, but the important information is located in the info bar at the bottom. In Fig. 2, it displays “5.18 MB / 1.16 MB Transferred”, which means that the website’s raw file size was 5.18 MB in total, but 1.16 MB after compression.
The “transferred” section just means the size of the data transmitted over the wire, which could be influenced by compressed files or cached ones.
One of the main reasons that Next.js websites are so large is because of the included React runtime. For every component with the "use client" directive, an entire React runtime is shipped to the client. Because I was using interactivity quite a lot, my website was needlessly multiple megabytes large.
Astro.js
Astro.js is a framework which takes a different approach. By default, it sends no React at all. When writing .astro files, only static documents are sent to the client, which are extremely lightweight. It also has a BYOF (Bring Your Own Framework) approach, allowing developers to use React, Svelte, Vue, Preact, or no frontend library at all.
I chose to use Preact with Astro, which is a 3kb alternative to React that effectively ships most features. This iteration of the website had a strong focus on minimizing unnecessary data being delivered to the client, so it was a reasonable choice.
Astro has wide compatibility with tools I’m used to, like Tailwind and MDX. In fact, because of Astro’s pre-configured MDX setup, code blocks and syntax highlighting came out-of-the-box.
Structure
This essay website has a different structure compared to most blogs. There are two distinct categories an essay can belong to: pieces and series. Pieces are one-off works of text found on the /essays page, and typically have no continuity with any other pieces. Series have a book-like structure. They have sections, and each section has multiple articles under it.
This structure was inspired by The Book of Shaders, and functionally works as a reading experience. The intent is that readers can start from the first article in the series and finish to the end, learning meaningful knowledge along the way, almost pedagogically.
Astro’s Content Collections API works wonderfully for this structure. With Zod schemas for article metadata, it’s trivial to keep organization consistent. I also developed a bespoke system for sorting the series articles into a tree-like structure, helped greatly by the API.
Performance Results
The finished homepage of this website has improved significantly compared to the Next.js version. By delivering only Preact components, maximizing static content, and using system fonts, I’ve achieved a network delivery of 128.17 KB / 54.16 KB, as shown in Fig. 3.
Read through this series to learn how I created this static, minimal website. That is all, and until next time, I am out.