Engineering · Journal
Build in public.
Notes from real work: what we built, what broke, what we measured, what we would do differently. Published when there is something worth saying - honestly irregular, never invented. First entries: building this website itself.
001 · A film you scroll: streaming 914 frames without a framework
Our homepage plays a 914-frame cinematic shot, scrubbed by scroll, with no video element and no front-end framework. The master frames are 3840×2160 PNGs - about 2.1 MB each, 2.5 GB total. Streaming those at scroll speed is impossible on real networks, and the first build proved it with stutter.
The fix was a derivative pipeline: every master is pre-rendered to a 1920px WebP at quality 70 - about 48-59 KB per frame, a 97.7% reduction, 55 MB for the whole film. The loader prefers the derivatives and never touches the masters in production. Frames decode through createImageBitmap with a resize hint so a decoded frame costs a fraction of full 4K, an LRU cache keeps ~36 frames alive around the playhead, and fetches are budgeted six at a time, biased in the scroll direction.
Two lessons worth keeping. First: the asset pipeline is the performance feature - no amount of clever runtime code makes 2 MB frames stream; one build step made 50 KB frames trivial. Second: an alpha:false canvas paints black before the first decode, which read as a broken site for ~300ms - the fix is pre-filling the canvas with the film’s paper colour so absence looks like atmosphere instead of failure.
002 · Five bugs worth writing down
Real defects from building this site, kept here because each one generalises:
- A later class quietly killed absolute positioning. A material class added
position:relative, overridingposition:absolutefrom an earlier rule - elements stacked in document flow and the layout “mysteriously” collapsed. Lesson: never let presentational classes ownposition. - A structural class name collided. A component named
.stagemet a page root also named.stage; an opacity meant for one blanked the other - the entire site rendered invisible. Lesson: structural class names are a global namespace; treat them like exports. background-clip:textwent invisible through children. Splitting a headline intoinline-blockword spans made the parent’s clipped gradient paint nothing - transparent text, no fill. Lesson: that technique only sees the element’s own text; animate colour and shadow instead when words are wrapped.- Windows display scaling lied to headless screenshots. At 125% OS scaling, headless Chromium’s layout viewport was window × 1.25 while the capture stayed window-sized - every mobile screenshot was silently cropped, and no flag fixed it. Lesson: QA mobile layouts through real device emulation (CDP), never through
--window-sizearithmetic. - An image pipeline reordered our operations. Extract-then-pad-then-resize, declared in one chain, executed in a different order and mis-cropped the brand mark. Lesson: when a fluent API is declarative about order, force materialisation between steps you need sequential.
All five cost real time; all five now cost you nothing. That is the point of a journal.
Related: The measured numbers · Architecture library · Engineering decisions