Layout thrashing: reflows repetidos en un frame y cómo detenerlos
Qué ocurre
El navegador intenta recalcular el layout una vez por frame. Pero si tu código escribe un estilo, luego lee una propiedad de geometría (offsetWidth, getBoundingClientRect) y vuelve a escribir — en un bucle — cada lectura fuerza un layout nuevo y síncrono de la página. Un bucle sobre 100 elementos puede provocar 100 reflows completos en un frame.
El coste es proporcional al tamaño del DOM, así que el mismo código que va bien en una página pequeña destruye el INP en una página con miles de nodos.
Cómo reconocerlo
- El presentation delay (trabajo de renderizado después del manejador) domina el desglose de INP.
- DevTools Performance muestra muchos bloques morados de Layout dentro de un frame, a menudo marcados como “Forced reflow”.
- El código alterna lecturas (offsetTop, clientHeight, getComputedStyle) y escrituras (style, classList) dentro de un bucle.
Cómo solucionarlo
- Agrupa primero todas las lecturas y luego todas las escrituras — nunca las intercales en un bucle.
- Mueve las escrituras a requestAnimationFrame para que se apliquen justo antes del siguiente repintado.
- Prefiere soluciones CSS (clases, transforms, flex/grid) antes que medir y posicionar elementos en JS.
Problema
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
})
Solución
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"
})
})
Escanea tu sitio gratis →