Paint profiling clean; no layout storms
Why it matters
Layout thrashing occurs when JavaScript alternates between DOM reads (which force the browser to recalculate layout) and DOM writes within the same synchronous block. A loop that reads el.offsetHeight then writes el.style.height for 50 elements triggers 50 layout recalculations instead of one. ISO 25010:2011 time-behaviour measures the cost; the user-visible outcome is continuous paint flashing and dropped frames during any interaction that touches DOM geometry — typically resizing, drag, and scroll handlers.
Severity rationale
Info because layout thrashing produces cosmetic jank and is difficult to trigger in synthetic tests, making it a polish-level issue rather than a blocking defect — though it can be severe on devices with constrained GPU memory.
Remediation
Separate all DOM reads from DOM writes by batching writes into a requestAnimationFrame callback. Read geometry values before the frame, apply changes inside the callback.
// components/resize-handler.ts — avoid layout thrashing
function resizeElements(elements: HTMLElement[]) {
// Phase 1: read all geometry (single layout pass)
const heights = elements.map((el) => el.offsetHeight)
// Phase 2: write all geometry in next frame (single repaint)
requestAnimationFrame(() => {
elements.forEach((el, i) => {
el.style.height = heights[i] + 10 + 'px'
})
})
}
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 Deep Dive Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- iso-25010:2011 · time-behaviour — Time Behaviour (performance efficiency)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-deep-dive·automated