CSS Animation Performance: width vs transform
How switching from width to transform: scaleX() fixed a janky mobile progress bar
#css#performance#animation#frontend
Had a janky progress bar on mobile. Switching from width to transform: scaleX() fixed it instantly.
Why the Difference
Understanding the browser rendering pipeline gives you the answer.
widthchange → Recalculate from Layout → Main thread blockingtransformchange → Composite only → GPU handles it
Real Example
// Before - reflow every frame
<div style={{ width: `${progress}%` }} />
// After - GPU-accelerated, no reflow
<div
className="w-full origin-left will-change-transform"
style={{ transform: `scaleX(${progress / 100})` }}
/>
The difference is dramatic for frequent animations like scroll events.
Key Takeaway
width,height→ Layout trigger → Main thread blockingtransform,opacity→ Composite only → GPU handles it
Mobile has a weaker main thread, so the difference is more noticeable.
Resources
- CSS Triggers - Check which properties trigger which steps
- Use
will-changeto hint the browser about upcoming changes