Layout thrashing: powtarzające się reflowy w jednej klatce i jak je zatrzymać
Co się dzieje
Przeglądarka stara się przeliczać układ raz na klatkę. Ale jeśli kod zapisuje styl, potem odczytuje właściwość geometrii (offsetWidth, getBoundingClientRect), potem znów zapisuje — w pętli — każdy odczyt wymusza świeży, synchroniczny układ strony. Pętla po 100 elementach może wywołać 100 pełnych reflowów w jednej klatce.
Koszt jest proporcjonalny do rozmiaru DOM, więc ten sam kod, który jest w porządku na małej stronie, niszczy INP na stronie z tysiącami węzłów.
Jak rozpoznać
- Presentation delay (praca renderowania po obsłudze) dominuje w rozbiciu INP.
- DevTools Performance pokazuje wiele fioletowych bloków Layout w jednej klatce, często oznaczonych „Forced reflow”.
- Kod naprzemiennie odczytuje (offsetTop, clientHeight, getComputedStyle) i zapisuje (style, classList) wewnątrz pętli.
Jak naprawić
- Najpierw zgrupuj wszystkie odczyty, potem wszystkie zapisy — nigdy nie przeplataj ich w pętli.
- Przenieś zapisy do requestAnimationFrame, aby trafiały tuż przed kolejnym renderowaniem.
- Preferuj rozwiązania CSS (klasy, transforms, flex/grid) zamiast mierzenia i pozycjonowania elementów w 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
})
Poprawka
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"
})
})
Przeskanuj swoją stronę za darmo →