Transform and opacity only
Transform and opacity skip layout and paint, so they stay smooth.
Emil Kowalskiemilkowal.ski
Emil Kowalskiemilkowal.skiA hardware-accelerated animation will remain smooth, no matter how busy the main thread is.
Emil Kowalskiemilkowal.skiUpdating the style directly on the element fixed the issue
From emil-design-eng; demo 3 recreates a Vaul bug.
Block the main thread
Press Block, or tick Keep busy and type.
requestAnimationFrameMain thread
requestAnimationFrame(step)longest frame –WAAPI transformCompositor
el.animate([{ transform }])el.animate(
[{ transform: "translateX(0)" }, { transform: "translateX(100%)" }],
{ duration: 1200, iterations: Infinity, direction: "alternate" }
);
What each property costs
Pick a property, then Run each pane.
Layout or paintBad
- Style
- Layout
- Paint
- Composite
–Compositor onlyGood
- Style
- Layout
- Paint
- Composite
–Variable vs direct transform
Drag a drawer, then raise Rows and Benchmark.
--swipe on the drawerBad
setProperty("--swipe", y)– ms/movetransform on drawerGood
style.transform = translateY(y)– ms/moveWhy it matters, pros and cons
Why it matters
Transform and opacity only composite; everything else relayouts or repaints.
Pros
- Smooth while scripts and hydration run.
- Siblings never reflow mid-animation.
- Cheap on low-end phones.
Cons
- Scale distorts text; real resizes need FLIP.
- Gestures still need per-frame JS; set transform directly.
- Too many promoted layers cost GPU memory.