Browser & Frontend Runtime
Render pipeline: rescue a janky list
Reading about layout thrash is not the same as pulling a real list out of it. Build a deliberately janky scrollable feed, profile it in DevTools, and apply the unit fix order — predict the stage, fix structurally, reach for the compositor last — until the frame numbers come back, with evidence at every step.
Turn the unit mental model into a reproducible engineering loop: profile the pipeline, attribute the slow stage, kill forced sync layout, route motion through the compositor, defend the GPU memory bound, and verify the fix with before/after frame metrics on real hardware.
Take a deliberately janky scrollable list (your own or a starter of 5,000+ rows) and bring it to a sustained 60 fps on a mid-range Android — no dropped frames during scroll, no Forced reflow warnings, GPU layer count under 30 — proving each step with DevTools measurements, not estimates.
- A before/after table: p95 frame duration, dropped-frame count, layout ms per frame, composite ms per frame, and live layer count — measured under the same scroll, not estimated.
- Zero Forced reflow while executing JavaScript warnings in the after trace at sustained scroll.
- The DevTools Frames track shows green (on-time) frames during scroll with no red dropped frames; the after p95 frame duration is under the budget for the target refresh rate.
- A one-paragraph write-up naming, for each fix, which stage it addressed and why it ranked where it did in the fix order (eliminate forced layout, route to compositor, skip off-screen work, only then tune).
- Add LoAF and INP instrumentation (PerformanceObserver for long-animation-frame plus the INP from web-vitals) and a one-page on-call runbook: read the four signals, map each to a pipeline stage, apply the fix ladder, verify.
- Add a passive: true audit — find every scroll/wheel/touchmove listener, mark the genuinely non-passive ones, and show compositor-thread scroll is restored where preventDefault is not needed.
- Add a Lighthouse CI gate on a PR that fails the build if INP regresses above 200 ms or CLS above 0.1, and a synthetic benchmark that diffs p95 frame duration against the main branch.
- Move a CPU-heavy per-row computation (e.g. markdown render or syntax highlight) into a Web Worker and show the main-thread scripting bars shrink while scroll stays at 60 fps.
This is the loop you will run in every real render incident: profile first, attribute the slow stage from the flame-strip colours, eliminate forced synchronous layout with a two-pass batch, route motion through the compositor with transform, skip off-screen work with content-visibility, defend GPU memory by scoping will-change, and verify with before/after frame numbers on real hardware. Doing it once on a janky toy list makes the production rescue muscle memory.