Compositor-only properties: transform, opacity, filter
Why some animations feel buttery, others jank
Browser rendering pipeline: Layout β Paint β Composite. Most CSS property changes trigger Layout (expensive). A few only run on the GPU's compositor (cheap).
Cheap (60fps even on phones):
transformβ translateX/Y, rotate, scale, skew.opacityβ fade in/out.filterβ blur, brightness, hue-rotate.
Expensive (drops below 60fps on phones):
width,height,margin,paddingβ triggers layout.top,left,right,bottomβ triggers layout.box-shadowβ triggers repaint.background-colorβ repaint (lighter than layout, still costs).
The rule
/* BAD β left triggers layout on every frame */
.slide { left: 0; transition: left 0.3s; }
.slide:hover { left: 100px; }
/* GOOD β translateX runs on the compositor */
.slide { transform: translateX(0); transition: transform 0.3s; }
.slide:hover { transform: translateX(100px); }ANY property that can be expressed as a transform should be β the visual result is identical but the performance is 10Γ better on mobile.
will-change
.modal { will-change: transform, opacity; }Hint to the browser: "promote this to its own GPU layer now." Use SPARINGLY β applying to many elements wastes memory. Best practice: add will-change only just BEFORE animating, remove after.
Sign up to start coding
Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial β card required, cancel anytime.
Sign up β free trial βFirst 15 lessons in each track are free. No card needed for those.