ESC

Type to search the knowledge base.

Reflow vs Repaint

Layout (reflow) vs paint (repaint): which CSS/DOM changes trigger which, and how to keep animations cheap.

intermediate3 min read
  • 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

  1. Don’t animate layout properties for primary motion.
  2. Batch DOM writes; separate read phases.
  3. Prefer transform/opacity transitions.
  4. Reduce tree size (virtualize).
  5. 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 scroll without rAF batching
  • Shadows/filters not animated at 60fps on large areas without profiling
  • will-change removed 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.

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