Comprenez les quatre phases du rendu navigateur pour savoir précisément quelles propriétés CSS coûtent cher et comment will-change agit sous le capot.
Ouvrir cette leçon dans KodokonLe navigateur transforme votre CSS en pixels via un pipeline en quatre phases : Style (calcul des valeurs), Layout (géométrie, aussi appelé reflow), Paint (rasterisation en pixels, le repaint) et Composite (assemblage des calques sur le GPU). La règle d'or : plus vous touchez une phase en amont, plus la facture est lourde, car toutes les phases suivantes sont rejouées. Modifier width ou top déclenche layout + paint + composite. Modifier color ou box-shadow saute le layout mais repeint. Seules transform et opacity peuvent être traitées par le thread compositeur seul : l'animation reste fluide même si le thread principal est bloqué par du JavaScript.
.slide-bad {
position: absolute;
transition: left 0.3s ease;
}
.slide-bad:hover { left: 120px; }
.slide-good {
transition: transform 0.3s ease;
}
.slide-good:hover { transform: translateX(120px); }Le navigateur est paresseux : il regroupe vos écritures de style et ne recalcule le layout qu'au prochain rafraîchissement. Mais certaines lectures JavaScript - offsetHeight, getBoundingClientRect(), scrollTop, getComputedStyle() sur une propriété géométrique - exigent des valeurs à jour. Si une écriture est en attente, le navigateur doit recalculer immédiatement et de façon synchrone : c'est le reflow forcé. Alterner lecture et écriture dans une boucle produit du layout thrashing : un reflow complet par itération au lieu d'un seul pour tout le lot.
const items = document.querySelectorAll('.item');
items.forEach((item) => {
const h = item.offsetHeight;
item.style.height = h * 2 + 'px';
});
const heights = [...items].map((i) => i.offsetHeight);
items.forEach((item, index) => {
item.style.height = heights[index] * 2 + 'px';
});Le compositing découpe la page en calques rasterisés indépendamment et assemblés par le GPU. will-change: transform demande la promotion de l'élément en calque dédié avant l'animation, évitant la rasterisation coûteuse au premier frame. Subtilité de spécification souvent ignorée : will-change doit produire les mêmes effets de bord que la propriété annoncée. Ainsi will-change: transform crée un contexte d'empilement et transforme l'élément en bloc conteneur pour ses descendants en position: fixed - exactement comme un vrai transform. Un simple hint de performance peut donc casser votre empilement ou vos éléments fixes.
const panel = document.querySelector('.panel');
panel.addEventListener('pointerenter', () => {
panel.style.willChange = 'transform';
});
panel.addEventListener('transitionend', () => {
panel.style.willChange = 'auto';
});