awesome-everything RU
↑ Back to the climb

Browser & Frontend Runtime

Render pipeline: rescue a janky list

Crux Hands-on project — take a janky scrollable list, diagnose each pipeline stage in DevTools, fix layout thrash and layer abuse, and prove 60 fps with before/after frame numbers.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 240 min

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.

Goal

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.

Project
0 of 7
Objective

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.

Requirements
Acceptance criteria
  • 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).
Senior stretch
  • 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.
Recap

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.

Continue the climb ↑What V8 is and why performance varies 100×
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.