Rendering Pipeline: Layout, Paint, Composite (and How to Avoid Jank)
A practical mental model of the browser rendering pipeline and how common coding patterns cause forced reflow, jank, and slow interactions.
Frontend Interview Team
March 01, 2026
What you’ll learn
- The browser pipeline: style → layout → paint → composite
- What “forced reflow” actually means
- Practical rules to avoid layout thrash
30‑second interview answer
The browser renders in stages: compute styles, layout (geometry), paint (pixels), then composite (layers). Performance problems happen when JS repeatedly reads layout (getBoundingClientRect) and writes layout-affecting styles in a tight loop, causing forced synchronous layout. The fix is batching reads/writes, avoiding layout-triggering properties, and leaning on compositing-friendly transforms for animations.
Mental model: read vs write
Bad pattern (layout thrash):
for (const el of items) {
const top = el.getBoundingClientRect().top; // READ layout
el.style.marginTop = `${top}px`; // WRITE layout
}This can force layout repeatedly.
Better pattern: batch reads then writes.
Properties that typically cause layout
width,heighttop/left(positioned elements)margin/padding
Properties that are often compositing-friendly:
transformopacity
Debugging in DevTools
Performance panel:
- look for “Recalculate Style” and “Layout” taking lots of time
- look for repeated layout events after JS
Production rule of thumb
- Batch DOM reads/writes.
- Animate with
transform/opacity. - Avoid measuring layout in hot paths (scroll/resize) without throttling.
Quick recap
- Layout is expensive; forced layout is worse.
- Avoid read/write interleaving.
- Prefer composited animations.
Performance checklist (copy/paste)
- Avoid read/write interleaving (
getBoundingClientRectthen style writes) - Throttle scroll/resize handlers
- Prefer
transform+opacityfor animations - Watch Layout/Style cost in Performance panel