Verstehe die vier Phasen des Browser-Renderings, damit du genau weißt, welche CSS-Eigenschaften teuer sind und wie will-change unter der Haube funktioniert.
Diese Lektion in Kodokon öffnenDer Browser verwandelt dein CSS über eine vierstufige Pipeline in Pixel: Style (Werte berechnen), Layout (Geometrie, auch Reflow genannt), Paint (das Rastern in Pixel, der Repaint) und Composite (das Zusammensetzen der Ebenen auf der GPU). Die goldene Regel: Je früher die Phase ist, die du berührst, desto höher die Rechnung, denn jede folgende Phase wird erneut durchlaufen. Ändern von width oder top löst Layout + Paint + Composite aus. Ändern von color oder box-shadow überspringt das Layout, malt aber neu. Nur transform und opacity können allein vom Compositor-Thread verarbeitet werden: Die Animation bleibt flüssig, selbst wenn der Hauptthread von JavaScript blockiert ist.
.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); }Der Browser ist faul: Er bündelt deine Stil-Schreibvorgänge und berechnet das Layout erst beim nächsten Refresh neu. Doch manche JavaScript-Lesevorgänge - offsetHeight, getBoundingClientRect(), scrollTop, getComputedStyle() auf einer geometrischen Eigenschaft - verlangen aktuelle Werte. Wenn ein Schreibvorgang aussteht, muss der Browser sofort und synchron neu berechnen: Das ist ein erzwungener Reflow. Lese- und Schreibvorgänge in einer Schleife abzuwechseln erzeugt Layout-Thrashing: ein vollständiger Reflow pro Durchlauf statt eines einzigen für den ganzen Stapel.
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';
});Compositing zerlegt die Seite in Ebenen, die unabhängig gerastert und von der GPU zusammengesetzt werden. will-change: transform fordert an, dass das Element vor der Animation auf eine eigene Ebene gehoben wird, was die teure Rasterung im ersten Frame vermeidet. Eine oft übersehene Feinheit der Spezifikation: will-change muss dieselben Nebenwirkungen erzeugen wie die Eigenschaft, die es ankündigt. So erzeugt will-change: transform einen Stacking-Context und macht das Element zu einem Containing Block für seine position: fixed-Nachfahren - genau wie ein echtes transform. Ein simpler Performance-Hinweis kann also deine Stapelreihenfolge oder deine fixierten Elemente zerbrechen.
const panel = document.querySelector('.panel');
panel.addEventListener('pointerenter', () => {
panel.style.willChange = 'transform';
});
panel.addEventListener('transitionend', () => {
panel.style.willChange = 'auto';
});