Folio vi · Articles
Published articles.
Articles about frontend infrastructure, CI/CD, system design, and the practical work behind reliable software.
- Articles
- 50
- Topics
- 99
- Reading time
- 12h 43m
- 01
We Blamed Vite For A 90-Second Local Load. The Real Bottleneck Was The 11,516 Modules We Asked It For.
A local Vite page took 90 seconds to load because eager route imports pulled 11,516 modules into one page load. Making routes lazy cut it to 54 modules and 10.54 seconds. The mechanism, how to count your own modules, and where the fix stops working.
Read article - 02
I Gave Claude 500 GB of Raw Footage. It Built a 29-Minute 4K Film.
A practical AI-assisted editing case study for first-time creators and experienced editors: 500 GB of footage, three rebuilds, custom cleanup, 3D maps and a finished 4K film.
Read article - 03
Every Browser Retry You Add Is A Small DDoS Attack. Stop Calling It Reliability.
Retries keep a single request alive, but at production scale they can turn an outage into a traffic multiplier. The browser needs a retry policy, not a setTimeout loop.
Read article - 04
loading="lazy" On Your Hero Image Waits For Your CSS. Same Page, Same Attribute: 16ms Slower In One Test, 428ms In The Next.
loading="lazy" on an above-the-fold image does not wait for a scroll, it waits for layout. Measured in Chromium, Firefox and WebKit: the lazy hero request starts right after the stylesheet lands, costing 16ms on one network profile and 428ms on another, why fetchpriority cannot rescue it, and why making everything eager is worse.
Read article - 05
setTimeout(fn, 0) Is Not Zero. In A Background Tab, Your 100ms Timer Runs Once A Minute.
The delay you pass to setTimeout is a minimum. Measured in Chromium, Firefox, WebKit and Node: the 4ms nesting clamp, hidden tabs throttled to 1 second, Chrome's once-a-minute intensive throttling after 5 minutes, a 30-day timer that fires instantly, and what to use instead.
Read article - 06
JavaScript Reads "2026-10-06" As UTC And "2026-10-06T00:00" As Local Time. Most Off-By-One Date Bugs Start There.
new Date("2026-10-06") is UTC midnight, new Date("2026-10-06T00:00") is local midnight. Tested in Chromium, Firefox and WebKit across three time zones: where the day slips, why Indian teams rarely see it, "06-10-2026" becoming 10 June, DST arithmetic, and what Temporal fixes.
Read article - 07
Chrome Stopped Running Your unload Handler. If Your Analytics Still Use It, Your Numbers Already Changed.
Since Chrome 154, unload handlers are off by default on every Chrome page load - they register without error and never run. Reproduced in Chromium: what it does to the Back button, which data quietly went missing during the seven-month rollout, and the pagehide pattern to use instead.
Read article - 08
Cache-Control: no-cache Does Not Mean Do Not Cache. And No Header At All Is Worse.
no-cache stores the response and revalidates it every time - no-store is the one that refuses to store. And an index.html with no Cache-Control at all is still cached, for a period the browser works out from Last-Modified. Reproduced in Chromium, with the two-rule setup I would use.
Read article - 09
Your Service Worker Is A Deploy You Cannot Roll Back. Stop Shipping It Like A Script.
Once a service worker is installed, the browser decides when your new release runs, and rollback cannot reach it. Why reloading does not activate a new worker, how skipWaiting breaks lazy chunks in open tabs, and the kill switch to write before you need it.
Read article - 10
VITE_ And NEXT_PUBLIC_ Are Not Naming Conventions. They Are Publish Buttons.
Renaming a variable so it stops being undefined pastes its value into a public JavaScript file. What client env prefixes really do at build time, the dynamic lookup that inlines every prefixed variable in Vite, the define config that leaked a whole shell environment, and a CI check that catches it.
Read article