Layout thrashing eliminated
Why it matters
Interleaving DOM reads and writes in a loop forces the browser to recalculate layout after every write before it can serve the next read — called "layout thrashing" (ISO-25010 time-behaviour). Reading element.offsetHeight after setting element.style.height on 100 elements triggers 100 synchronous layout recalculations instead of one. On a 60Hz display, each recalculation costs approximately 16ms of budget. One thrashing loop can consume the entire frame budget, causing the browser to drop frames and producing visible jank.
Severity rationale
Low because layout thrashing causes visible jank and dropped frames during the specific interaction that triggers it, but does not affect baseline performance outside those code paths.
Remediation
Batch all DOM reads before any DOM writes. Read from the DOM, store the values, then write back in a separate pass:
// Bad: interleaved read-write causes layout thrashing
for (const el of elements) {
el.style.height = el.scrollHeight + 'px' // read then write on every iteration
}
// Good: batch reads first, then batch writes
const heights = Array.from(elements).map(el => el.scrollHeight) // all reads
elements.forEach((el, i) => { el.style.height = heights[i] + 'px' }) // all writes
For animation-related mutations, wrap batched writes in requestAnimationFrame:
requestAnimationFrame(() => {
const updates = Array.from(elements).map(el => ({ el, height: el.scrollHeight }))
updates.forEach(({ el, height }) => { el.style.height = `${height}px` })
})
Use the FastDOM library or Chrome DevTools Performance tab → Layout to identify thrashing code paths.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Performance Core Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- iso-25010:2011 · performance-efficiency.time-behaviour — Time Behaviour
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-core·automated