Skip to main content

/writing

Rebuilding my personal site

· 3 min read

I rewrote my personal site. Every route had to score well on performance, accessibility, best practices and SEO, and the visual treatment was not allowed to get quieter to make that happen.

What came out is a small static site with a few interactive pieces, an animated backdrop that turns itself off under reduced motion, and a design system page that documents itself.

Static-first with no client framework

The site is mostly text with some decoration, so a static-first framework is the right shape. Every component renders to HTML by default, and the only JavaScript that ships is what a page explicitly mounts.

An earlier version used a thin client framework to wrap the heavy pieces, a rotating globe and a WebGL backdrop. The wrapper was doing nothing. The real work lived in libraries that were not framework-specific, and the wrapper only mounted them. Removing it dropped about ten kilobytes gzipped of runtime that no UI was using.

The interactive pieces now mount through plain script blocks, and each one gates itself. The globe waits until the hero scrolls into view. The backdrop checks prefers-reduced-motion and only imports its implementation if motion is allowed. The question is not how fast something loads. It is whether it should load at all for this person.

Reduced motion as a real signal

The backdrop is heavy. For anyone with prefers-reduced-motion set, none of it loads: the implementation sits behind a dynamic import gated on matchMedia, so that group pays zero bytes for something they will never see. Every other animation on the site has the same branch, gated as high up as the asset graph allows.

Build-time over runtime

Open Graph images, structured metadata, the RSS feed, the sitemap, image variants and the audit that gates each deploy all happen at build time. No headless browser in the pipeline, no fonts installed at deploy, no cold start on the first request.

There is also a /system page listing every color, font and motion curve in use. It reads from the same token source as the rest of the site, so the documentation cannot drift from the implementation.

A page for the music

There is a /music page with the tracks I keep nearby: what is on rotation, the all-time list, favorite mix compilations, and a separate cut of Brazilian songs from home. The data is a flat file and the rendering uses the same Section primitive as everything else.

Holding the line

The constraint held. Every route still audits at ninety-nine or better on performance and full marks on accessibility, best practices and SEO, and the audit runs on every deploy rather than when I remember to check. The visual treatment did not get quieter to make that happen, which was the part I was most worried about giving up.

What I cut

The client framework that wrapped canvas mounts and earned nothing. Hydration nobody would see. Shims for tools I do not use. Animations for people who asked not to have them. Convenience layers that pay off on a different shape of project.

The site is small, builds in three seconds, and audits in under a minute.