debugcssModeratepending
Debug: CSS animations janky or not smooth
Viewed 0 times
animationtransformopacitywill-changeGPUcompositor60fps
Error Messages
Problem
CSS animations are choppy, janky, or cause layout shifts. Not running at 60fps.
Solution
Optimize animations for GPU compositing:
GOOD (GPU accelerated, no reflow):
- transform (translate, scale, rotate)
- opacity
BAD (triggers reflow/repaint):
- width, height
- top, left, right, bottom
- margin, padding
- font-size
- border-width
/ BAD - triggers layout: /
.animate { left: 100px; transition: left 0.3s; }
/ GOOD - GPU composited: /
.animate { transform: translateX(100px); transition: transform 0.3s; }
.animated-element {
will-change: transform; / Hint to browser /
}
/ Remove will-change when animation ends (saves memory) /
function animate() {
element.style.transform =
requestAnimationFrame(animate);
}
// BAD - read then write in loop:
elements.forEach(el => {
const h = el.offsetHeight; // Read (forces layout)
el.style.height = h + 10 + 'px'; // Write (invalidates layout)
});
// GOOD - batch reads, then batch writes
Look for: Long frames, Layout shifts, Paint events
Enable: Rendering > Paint flashing (green = repaint)
- Only animate compositor-friendly properties:
GOOD (GPU accelerated, no reflow):
- transform (translate, scale, rotate)
- opacity
BAD (triggers reflow/repaint):
- width, height
- top, left, right, bottom
- margin, padding
- font-size
- border-width
- Use transform instead of position:
/ BAD - triggers layout: /
.animate { left: 100px; transition: left 0.3s; }
/ GOOD - GPU composited: /
.animate { transform: translateX(100px); transition: transform 0.3s; }
- Promote to own layer:
.animated-element {
will-change: transform; / Hint to browser /
}
/ Remove will-change when animation ends (saves memory) /
- Use requestAnimationFrame for JS animations:
function animate() {
element.style.transform =
translateX(${x}px);requestAnimationFrame(animate);
}
- Avoid layout thrashing:
// BAD - read then write in loop:
elements.forEach(el => {
const h = el.offsetHeight; // Read (forces layout)
el.style.height = h + 10 + 'px'; // Write (invalidates layout)
});
// GOOD - batch reads, then batch writes
- Debug: Chrome DevTools > Performance > Record
Look for: Long frames, Layout shifts, Paint events
Enable: Rendering > Paint flashing (green = repaint)
Revisions (0)
No revisions yet.