Optimizing browser rendering for smoother web experiences.
When you interact with a website, your browser is constantly working behind the scenes to render the page. This involves several steps, two of the most critical being Reflow (also known as Layout) and Repaint (also known as Paint). Understanding these processes is key to building high-performance web applications.
In simple terms:
A Reflow occurs when the browser needs to recalculate the layout of a part of the document (or the whole document). This happens when changes are made to the DOM (Document Object Model) or CSS that affect the geometry of elements. Because elements often affect each other's positions, a single reflow can trigger a cascade of recalculations across the entire page, making it a very expensive operation.
width
, height
, padding
, margin
, border
, font-size
, position
, float
, display
).:hover
that change layout-affecting properties.offsetWidth
, offsetHeight
, getComputedStyle()
, etc., as these force the browser to perform a reflow to give you accurate values.Observe how changes to layout properties cause all elements to shift and trigger a "Reflow". The entire container will flash red.
Reflow Count: 0
A Repaint occurs when changes are made to an element's visual properties that do not affect its layout. The browser simply redraws the pixels for that element on the screen. Repaints are less expensive than reflows because they don't require recalculating the geometry of other elements.
color
, background-color
, visibility
(but not display
), outline
, text-decoration
, box-shadow
.transform: translate()
, scale()
, rotate()
) and opacity
changes are often optimized by browsers to trigger only repaints (or even just compositing, which is even cheaper).Observe how changes to visual properties cause only the affected element to redraw and trigger a "Repaint". Only the changed box will flash green.
Repaint Count: 0
It's important to understand that a Reflow will always trigger a Repaint. If the browser has to recalculate the layout of elements, it then needs to redraw those elements in their new positions. However, a repaint does not necessarily cause a reflow. This is why minimizing reflows is generally a higher priority for performance optimization.
Reducing unnecessary reflows and repaints is crucial for smooth animations and a responsive user interface. Here are some strategies:
// Bad (multiple reflows/repaints)
element.style.width = '100px';
element.style.height = '50px';
element.style.margin = '10px';
// Good (single reflow/repaint)
element.classList.add('new-styles');
// .new-styles { width: 100px; height: 50px; margin: 10px; }
offsetWidth
, clientHeight
, getComputedStyle()
) immediately after modifying layout properties will force the browser to perform a synchronous reflow to give you the correct, up-to-date value.
// Forces a reflow here
element.style.width = '200px';
const currentWidth = element.offsetWidth; // Forces reflow
element.style.height = '100px'; // Another reflow
transform
(e.g., translate
, scale
, rotate
) and opacity
can often be handled by the browser's compositor, avoiding both reflows and repaints, leading to much smoother animations.
/* Triggers reflow */
.animate-width {
width: 200px;
transition: width 0.3s;
}
/* Triggers only compositing (most performant) */
.animate-transform {
transform: translateX(100px);
transition: transform 0.3s;
}
will-change
: This CSS property hints to the browser about what properties will change, allowing it to optimize rendering ahead of time. Use it sparingly and only for properties that are actually going to change significantly.
.animated-element {
will-change: transform, opacity;
}
position: absolute
or fixed
: Elements positioned absolutely or fixed are taken out of the normal document flow. Changes to their geometry will not affect the layout of other elements, thus limiting the scope of reflows.
This flowchart illustrates the typical steps a browser takes to render a web page.