Layout-Thrashing: wiederholte Reflows in einem Frame und wie du sie stoppst
Was passiert
Der Browser versucht, das Layout einmal pro Frame neu zu berechnen. Aber wenn dein Code einen Stil schreibt, dann eine Geometrie-Eigenschaft liest (offsetWidth, getBoundingClientRect) und wieder schreibt — in einer Schleife — erzwingt jeder Lesezugriff ein frisches, synchrones Layout der Seite. Eine Schleife über 100 Elemente kann 100 vollständige Reflows in einem Frame auslösen.
Die Kosten sind proportional zur DOM-Größe, daher zerstört derselbe Code, der auf einer kleinen Seite in Ordnung ist, den INP auf einer Seite mit Tausenden Knoten.
So erkennst du es
- Der Presentation Delay (Rendering-Arbeit nach dem Handler) dominiert die INP-Aufschlüsselung.
- Die DevTools Performance zeigen viele violette Layout-Blöcke in einem Frame, oft als „Forced reflow“ markiert.
- Der Code wechselt innerhalb einer Schleife zwischen Lesen (offsetTop, clientHeight, getComputedStyle) und Schreiben (style, classList).
So behebst du es
- Bündle zuerst alle Lesezugriffe, dann alle Schreibzugriffe — verschachtle sie nie in einer Schleife.
- Verlagere Schreibzugriffe in requestAnimationFrame, damit sie genau vor dem nächsten Paint landen.
- Bevorzuge CSS-Lösungen (Klassen, Transforms, Flex/Grid) gegenüber dem Messen und Positionieren von Elementen in JS.
Problem
items.forEach((el) => {
el.style.width = base + "px" // write
const h = el.offsetHeight // read → forced reflow, every iteration
el.style.height = h * 2 + "px" // write
})
Lösung
const heights = items.map((el) => el.offsetHeight) // all reads
requestAnimationFrame(() => {
items.forEach((el, i) => { // all writes
el.style.width = base + "px"
el.style.height = heights[i] * 2 + "px"
})
})
Scanne deine Website kostenlos →