Reflow and repaint
Reflow is the recalculation of the page geometry (layout), and repaint is redrawing the pixels of elements whose geometry is already known (paint). When you change the DOM or CSS, the rendering engine (Blink in Chrome) has to recompute how the page looks, and that work splits into exactly these stages.
Theory
TL;DR
- Reflow (layout): recalculating sizes, positions and spacing; repaint (paint): redrawing visible pixels without changing geometry.
- Almost every reflow causes a repaint, but not every repaint needs a reflow.
- Reflow is caused by
width,height,margin,padding,font-size, adding and removing nodes, changing text, resize, scroll. - Repaint is caused by
color,background-color,box-shadow,outline,visibility. - Reading
offsetWidth,clientHeightorgetComputedStyle()right after writing a style forces the browser into a synchronous layout (a forced reflow). - The cheapest path is composite: animate
transformandopacityonly, they bypass layout and paint.
Quick example
const el = document.querySelector('.box');
el.style.width = '400px'; // reflow + repaint: geometry changed
el.style.backgroundColor = 'red'; // repaint only: appearance changed
el.style.transform = 'scale(1.1)'; // composite only, work for the GPU
// The worst pattern: write, then immediately read a layout property
el.style.width = '500px';
console.log(el.offsetHeight); // forced synchronous layout right hereWhat the browser does at each stage
| Term | What it does | When it happens |
|---|---|---|
| Reflow (layout) | Recalculates element geometry: sizes, positions, spacing, height, width | When the DOM structure or CSS that affects layout changes |
| Repaint (paint) | Redraws the visible pixels (colors, background, shadows, borders) without recalculating geometry | When only the appearance changes, not the size or the position |
Under the hood the sequence is this.
Reflow forces the browser to:
- Recalculate sizes and positions of elements (the layout tree).
- Determine which regions of the screen have to be redrawn.
- Run the repaint.
Repaint fills in the changed pixels, and then composite glues the layers together.
Almost every
reflowcauses arepaint, but not everyrepaintrequires areflow.
What triggers reflow and what triggers repaint
Reflow is triggered by:
- size changes:
width,height,padding,margin,border,font-size; - adding or removing DOM elements;
- changing text;
- reading properties that depend on layout:
offsetWidth,clientHeight,getComputedStyle(); - changing a class that affects positioning or sizes;
- resizing the browser window;
- scrolling.
element.style.width = '400px'; // reflow + repaintRepaint is triggered by:
- color changes:
color,background-color; - opacity changes via
opacity; - shadows
box-shadow; outline;visibility, when the element stays in place.
element.style.backgroundColor = 'red'; // repaint onlyWhy reflow is dangerous for performance
Reflow is one of the most expensive operations in the browser, especially when it touches many elements.
- The layout tree is connected: changing one element can force the whole document to be recalculated.
- A single reflow on a complex layout can take tens of milliseconds.
Do it in a loop or very often and the interface starts to stutter.
Reflow and repaint happen in the frame rendering phase, between the macrotasks and microtasks of the event loop. For a smooth animation you must fit into 16.6 ms per frame (60 FPS). If layout takes longer, frames are dropped and the user sees freezes.
How to reduce the number of reflows and repaints
| Approach | What it gives |
|---|---|
| Batch updates | Change several properties at once, through classList or cssText, instead of separate assignments |
| DocumentFragment | Build DOM elements outside the document and insert everything in one go |
| Cache the measurements | const height = el.offsetHeight; once before the loop, not inside it |
| Do not animate layout properties | Avoid animating width, height, top, left |
| CSS transform and opacity | GPU animations do not cause a reflow |
| requestAnimationFrame() | For animations instead of setInterval |
| will-change | Tells the browser in advance which properties will change so it can promote the element to its own layer |
An example of bad code where reflow happens hundreds of times:
for (let i = 0; i < 100; i++) {
const el = document.createElement('div');
document.body.appendChild(el); // reflow every time
el.style.width = i + 'px'; // reflow
console.log(el.offsetHeight); // forced reflow
}The optimized version with a single reflow:
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const el = document.createElement('div');
el.style.width = i + 'px';
fragment.appendChild(el);
}
document.body.appendChild(fragment); // one reflowSummary table
| Term | What it does | Example | Impact |
|---|---|---|---|
| Reflow (layout) | Recalculation of geometry and positions | changing width, margin, adding DOM | expensive operation |
| Repaint (paint) | Redrawing the appearance | changing color, background, opacity | moderately costly |
| Composite | Gluing the layers after paint | transform, opacity | cheap, runs on the GPU |
| Goal | Minimize reflow, animate only transform and opacity | maximum FPS |
Common mistakes
| Mistake | What happens |
|---|---|
| Changing style repeatedly with separate assignments | A new reflow is triggered every time |
Reading offsetHeight right after changing a style | The browser is forced into a synchronous layout |
| Changing classes inside a loop | A reflow on every iteration |
Animating properties that affect layout (width, top, margin) | Layout is recalculated on every frame |
| Appending DOM elements one by one | Every insert causes a recalculation of the tree |
Two more classics. People assume opacity is always free, but it is cheap only when the element is already promoted to its own compositing layer; otherwise a repaint still happens. And slapping will-change on everything backfires: every layer costs memory, so redundant layers hurt performance instead of helping it.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.