Reflow Triggers
Reflow Triggers
Section titled “Reflow Triggers”Introduction
Section titled “Introduction”Reflow (also called layout) recalculates the position and size of elements. It’s the most expensive part of the rendering pipeline because changes to one element can affect the entire document.
What Triggers Reflow
Section titled “What Triggers Reflow”DOM Changes
Section titled “DOM Changes”// ❌ Adding/removing elements triggers reflowdocument.body.appendChild(newElement);
// ❌ Changing element visibilityelement.style.display = 'none'; // Triggers reflowelement.style.visibility = 'hidden'; // Only repaint ✓Dimension Changes
Section titled “Dimension Changes”// All of these trigger reflowelement.style.width = '100px';element.style.height = '200px';element.style.margin = '10px';element.style.padding = '20px';element.style.borderWidth = '2px';element.style.position = 'absolute';element.style.top = '50px';Font & Text Changes
Section titled “Font & Text Changes”// Font changes recalculate all text layoutselement.style.fontSize = '16px';element.style.fontFamily = 'Arial';element.style.lineHeight = '1.5';element.style.fontWeight = 'bold';Reading Layout Properties
Section titled “Reading Layout Properties”Reading certain properties forces a synchronous reflow to return the correct value:
// These force an immediate reflow (layout thrashing!)element.offsetWidth; // Forces layoutelement.offsetHeight; // Forces layoutelement.offsetTop; // Forces layoutelement.getBoundingClientRect(); // Forces layoutelement.scrollTop; // Forces layoutelement.clientWidth; // Forces layoutwindow.getComputedStyle(element); // Forces layoutForced Reflow (Layout Thrashing)
Section titled “Forced Reflow (Layout Thrashing)”Reading then writing alternately causes multiple reflows:
// ❌ Layout thrashing - forces 3 reflows!const h1 = element.offsetHeight; // Read → forced layoutelement.style.height = h1 + 10 + 'px'; // Write → layoutconst h2 = element.offsetHeight; // Read → forced layout again!
// ✅ Batch reads first, then writesconst height = element.offsetHeight; // Read onceelements.forEach(el => { el.style.height = (height / 2) + 'px'; // Write many, layout once});Minimizing Reflow
Section titled “Minimizing Reflow”// 1. Use CSS classes instead of inline styleselement.classList.add('card--expanded');
// 2. Use requestAnimationFrame for visual changesrequestAnimationFrame(() => { element.style.transform = 'translateX(100px)';});
// 3. Use DocumentFragment for batch insertsconst fragment = document.createDocumentFragment();items.forEach(item => fragment.appendChild(buildElement(item)));container.appendChild(fragment); // Single reflow
// 4. Use content-visibility for off-screen content// CSS: content-visibility: auto; contain-intrinsic-size: 500px;
// 5. Use will-change to hint at upcoming changes// CSS: will-change: transform, opacity;Summary
Section titled “Summary”- Reflow is triggered by DOM changes, dimension changes, font changes, and reading layout properties
- Layout thrashing happens when you alternate read/write operations
- Batch reads before writes to minimize reflows
- Use
DocumentFragment,requestAnimationFrame, and CSS classes for efficiency