Engineering log / rodionbelousov.studio

What broke, and what it cost.

Anyone can show the finished surface, and by now anyone can generate one. This is the part that does not come out of a prompt: the things that were wrong first, how they were found, and the two entries where the right answer was to throw the work away.

08 entriesEvery number here was measured, not estimated.
  1. 08
    BUNDLING / REVERTED

    The optimisation that cost 42 KB

    Making three.js a dynamic import, so devices that skip the WebGL backdrop could skip the download too. It worked - and the shared chunk grew from 528 KB to 674 KB, because a dynamic import forces the bundler to keep the whole namespace instead of tree-shaking it. That is 42 KB added for every ordinary visitor to save a minority, and it pulled the download forward into the window that decides LCP. Reverted the same hour it was written.

  2. 07
    CODEC / DROPPED

    The codec that won on paper

    AV1 was encoded next to H.264 for all three films. It cut the two 1080p30 clips by up to 78% - and came out larger than H.264 on the 60fps one, because a single CRF number does not map to the same quality across codecs. Shipping it meant per-file tuning plus format negotiation in four components, for a win that reverses on one file in three and that iOS largely cannot use. Measured, then dropped.

  3. 06
    TYPOGRAPHY / ANDROID

    Hyphenation only breaks where the dictionary exists

    A case title carried hyphens:auto, added so that long German headings would break cleanly. Android Chrome ships the hyphenation dictionary; desktop Linux mostly does not. So the title split as FIDIC - fi- / dic.uz on a phone, and looked perfect on every machine it was built on. Both halves fit their own line down to 320px, so the space was the only break ever wanted.

  4. 05
    SCROLL LOCK

    A loading screen that could never end

    The intro held overflow:hidden and touch-action:none on the document while it played. Every path that released that lock lived inside the animation-frame loop - including the failsafe, which was itself a line of that loop. So anything that stopped the loop left the page painted, readable and permanently unscrollable, recoverable only by reloading. The release now also hangs off a plain timer that fires whether or not a single frame is ever served. Verified by stubbing out requestAnimationFrame entirely.

  5. 04
    MEDIA / 12.75 MB

    The film that downloaded before anyone asked for it

    A scroll-scrubbed film shipped with its source and preload=auto written straight into the markup, for a section that starts three screens down the page. Every visitor pulled all 12.75 MB of it from first paint. On a phone on a weak connection the page painted in about a second and then sat there feeling frozen, because the connection stayed saturated for minutes behind it. The source now attaches only as the section approaches, and not at all under Save-Data. Home page transfer went from 12.92 MB to 0.16 MB.

  6. 03
    I18N / ROUTING

    The locale trap

    Localized clones of the homepage lived at /en/ and /de/, and the wordmark pointed at them. Switching language on a service page stranded you on a duplicate with no way back. The clones are gone, 301'd to the real home, and locale now applies only to real localized content.

  7. 02
    REDUCED MOTION

    Reduce Motion is not an off switch

    The preloader froze its object with animation-play-state: paused. On any phone with Reduce Motion enabled that read as a broken page - a cube standing still. It now turns slowly instead of dying.

  8. 01
    WEBGL / MOBILE GPU

    Mobile pays a different price

    The archive rendered every frame twice: the scene into a render target, then a fullscreen composite for grain and vignette. On a phone GPU that memory bandwidth is the entire budget. It now draws straight to the screen and only spins the composite up while a transition wipe is running.

This list only gets longer. That is the point of it.

See the systems these came out of