Reflow (layout) recalculates element geometry, while repaint redraws visual styles without changing layout geometry. Learn what triggers each phase, why forced reflow hurts runtime performance, and how to reduce layout thrashing in modern frontend code.
What is the difference between reflow and repaint in browsers?
The core idea
Browsers render in stages. The two most asked stages are:
- Reflow (layout): recalculate element size/position.
- Repaint: redraw pixels (colors, shadows, visibility) without changing geometry.
Reflow is usually more expensive because geometry changes can cascade through large parts of the DOM tree.
Stage | What changes | Typical triggers | Relative cost |
|---|---|---|---|
Reflow (Layout) | Box size/position and document flow | Changing width/height, font-size, DOM insertions/removals | High |
Repaint | Visual appearance only | Changing color/background/visibility/outline | Medium |
Composite | Layer composition on GPU | Transform/opacity updates on isolated layers | Lower (often) |
const box = document.querySelector('.box');
// Repaint only (no geometry change):
box.style.backgroundColor = 'tomato';
// Reflow + repaint (geometry changes):
box.style.width = '320px';
box.style.padding = '24px';
What makes reflow expensive
Layout changes can invalidate measurements of nearby or ancestor elements. On large pages, one geometry change can force the browser to recalculate positions for many nodes.
This becomes visible as scroll jank, delayed input response, and dropped frames during animations.
Forced synchronous reflow (layout thrashing)
A common performance bug: write styles, then immediately read layout metrics, repeatedly in a loop. Reading layout properties after writes can force the browser to flush layout right away.
const items = document.querySelectorAll('.item');
// ❌ Layout thrashing: write -> read in each iteration
for (const item of items) {
item.style.width = item.clientWidth + 10 + 'px'; // read after prior writes
}
// Reads like offsetWidth/clientWidth/getBoundingClientRect
// can trigger forced layout when styles are dirty.
const items2 = document.querySelectorAll('.item');
// ✅ Better: batch reads first, then batch writes
const widths = Array.from(items2, (el) => el.clientWidth);
requestAnimationFrame(() => {
items2.forEach((el, i) => {
el.style.width = widths[i] + 10 + 'px';
});
});
Goal | Preferred tactic | Why it helps |
|---|---|---|
Avoid layout thrash | Batch reads and writes separately | Prevents repeated forced reflow in loops. |
Smooth animations | Animate | Often avoids layout and heavy paint work. |
Limit blast radius | Use CSS | Reduces how far layout invalidation spreads. |
Lower DOM churn | Coalesce DOM updates (fragments/virtual DOM batching) | Fewer layout/paint cycles per interaction. |
How to diagnose in DevTools
Record a trace in the Performance panel while reproducing jank:
- Look for frequent Layout events and long Paint tasks.
- Correlate long frames with JavaScript that reads layout after style writes.
- Check whether animation steps stay near the 16.7ms/frame budget (60fps target).
.card {
/* isolate layout/paint when appropriate */
contain: layout paint;
}
/* Prefer transform for motion instead of top/left when possible */
.bad-move { top: 20px; left: 20px; }
.good-move { transform: translate(20px, 20px); }
Interview one-liner
Reflow recalculates layout geometry and is generally more expensive; repaint redraws visuals without layout changes. Optimize by minimizing layout invalidations, batching DOM reads/writes, and animating transform/opacity where possible.
Practical scenario
A filter sidebar updates result-card dimensions on every keystroke, causing repeated layout reads and writes that create visible typing lag.
Common pitfalls
- Reading
getBoundingClientRect()right after multiple style mutations. - Animating
top/left/widthfor high-frequency transitions. - Ignoring trace data and guessing performance bottlenecks.
Measure before and after in DevTools and RUM. Compare frame times and INP when switching from layout-triggering animations to transform/opacity patterns.
Think of reflow as moving furniture around a room (positions change), while repaint is changing wall color (same layout, new appearance). Moving furniture takes more work.
Use the relevant interview-question hub first, then move into a concrete study plan before targeted company sets.