Layout thrashing : reflows répétés dans un frame et comment les arrêter
Ce qui se passe
Le navigateur essaie de recalculer la mise en page une fois par frame. Mais si votre code écrit un style, puis lit une propriété de géométrie (offsetWidth, getBoundingClientRect), puis écrit à nouveau — dans une boucle — chaque lecture force une mise en page fraîche et synchrone de la page. Une boucle sur 100 éléments peut déclencher 100 reflows complets dans un frame.
Le coût est proportionnel à la taille du DOM : le même code, sans problème sur une petite page, détruit l'INP sur une page avec des milliers de nœuds.
Comment le reconnaître
- Le presentation delay (travail de rendu après le gestionnaire) domine la décomposition de l'INP.
- DevTools Performance affiche de nombreux blocs Layout violets dans un même frame, souvent signalés « Forced reflow ».
- Le code alterne lectures (offsetTop, clientHeight, getComputedStyle) et écritures (style, classList) dans une boucle.
Comment corriger
- Regroupez d'abord toutes les lectures, puis toutes les écritures — ne les entremêlez jamais dans une boucle.
- Déplacez les écritures dans requestAnimationFrame pour qu'elles s'appliquent juste avant le prochain rendu.
- Préférez les solutions CSS (classes, transforms, flex/grid) à la mesure et au positionnement d'éléments en JS.
Problème
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
})
Correctif
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"
})
})
Analysez votre site gratuitement →