Reflow vs Repaint
Layout (reflow) vs paint (repaint): which CSS/DOM changes trigger which, and how to keep animations cheap.
- browser
- reflow
- repaint
- layout
- rendering
Reflow (layout) recalculates geometry — sizes and positions. Repaint fills pixels for visual properties that don’t necessarily change layout (color, shadows). Both cost main-thread time; reflow usually costs more and can invalidate large subtrees. Knowing which you triggered is half of rendering performance.
Docs: Rendering performance — web.dev, CSS triggers, Pipeline.
Definitions
| Term | Updates | Typical properties |
|---|---|---|
| Reflow / layout | Geometry | width, height, top/left, fonts, content, display |
| Repaint | Pixels in layers | color, background, box-shadow, outline |
| Composite | Layer glue | transform, opacity (often) |
/* Layout */
.box { width: 50%; }
/* Paint-ish */
.box { background: #111; }
/* Often composite-only when layered */
.box { transform: translateX(8px); opacity: 0.9; }
Exact costs depend on browser engine and layerization — measure rather than memorize every property.
Forced synchronous layout
el.style.width = '200px'; // dirty layout
const h = el.offsetHeight; // forces reflow NOW
el.style.height = h + 10 + 'px';
Reading geometry (offset*, client*, getBoundingClientRect, getComputedStyle in some cases) flushes pending style/layout. In a loop, this is layout thrashing — Avoiding layout thrashing.
Batching pattern
// reads
const widths = items.map((el) => el.offsetWidth);
// writes
items.forEach((el, i) => {
el.style.width = widths[i] * 2 + 'px';
});
Or write via classes and let the browser pipeline naturally before the next frame.
Visualizing in DevTools
Performance recording → Layout purple bars vs Paint. Many layouts on scroll = scroll jank. Prefer compositor animations for continuous motion — Compositor layers.
Practical rules
- Don’t animate layout properties for primary motion.
- Batch DOM writes; separate read phases.
- Prefer
transform/opacitytransitions. - Reduce tree size (virtualize).
- Use
content-visibility/ containment where they fit.
Interview out-loud
“Reflow is layout geometry; repaint is pixel filling. Geometry reads can force sync layout. I batch reads and writes and animate transform/opacity so continuous UI avoids layout and heavy paint.”
Animation PR checklist
- Primary motion uses transform/opacity
- No layout reads inside
scrollwithout rAF batching - Shadows/filters not animated at 60fps on large areas without profiling
-
will-changeremoved after animation ends
Microbench caution
Do not trust microbenchmarks that toggle classes in a tight loop without user-visible frames. Use Performance panel on a real component at throttled CPU. Sometimes a single layout of a complex table is fine; thrashing it on every keystroke is not. Optimize the interaction path you can name in a user story.
Related
Further depth
Teams often under-invest in this topic until an incident or CWV regression. Schedule a one-hour drill: reproduce the failure mode in DevTools, list the top three mitigations for your stack, and file tickets with owners. Revisit after the next major feature that touches networking, rendering, auth, or third parties — those are the moments regressions land. Keep primary documentation links in the runbook so on-call is not searching chat history at 2am.
Concrete artifacts to leave behind: a short architecture note, a CI assertion or header snapshot, and a dashboard panel (lab or field) that would have caught the last bug. Teaching the rest of the team the mental model matters as much as the one-line fix.
Further reading
Related guides
- Compositor LayersWhen browsers promote layers, why transform/opacity animate cheaply, and layer explosion costs.
- Main Thread vs Compositor ThreadWhat runs on the main thread vs compositor, why scroll can be smooth while clicks feel dead, and fix strategies.
- Browser Rendering PipelineFrom bytes to pixels — parse, style, layout, paint, composite — and how your JS/CSS kicks each stage.
- BFCache Back Forward CacheHow the back/forward cache freezes pages for instant history nav, what blocks it, and how to restore state safely.
- Browser DevTools Network PanelRead waterfalls, timing phases, headers, throttling, and initiator chains in the Network panel like a production debugger.