Animation frame budget of 16ms maintained
Why it matters
At 60fps, each animation frame has a 16ms budget. Any JavaScript that runs synchronously inside a frame — including a setInterval callback or a DOM layout read followed by a write — can consume that budget entirely, causing the browser to skip the frame and produce visible stutter. ISO 25010:2011 time-behaviour captures the responsiveness requirement; the user-visible failure is an animation that stutters at irregular intervals, particularly during scroll or on lower-powered devices.
Severity rationale
Info because frame-budget violations produce cosmetic jank rather than functional failures — they are worth fixing for polish and accessibility but do not prevent users from completing tasks.
Remediation
Replace setInterval-driven animations with CSS transitions or requestAnimationFrame. For values that animate over time, CSS transform and opacity are GPU-composited and do not trigger layout.
/* components/animated-card.module.css — GPU-composited animation */
.card {
transition: transform 0.25s ease, opacity 0.25s ease;
will-change: transform; /* hint GPU layer promotion */
}
.card:hover {
transform: translateY(-4px);
}
For JS-driven values, schedule work with requestAnimationFrame rather than setInterval to stay synchronized with the browser's paint cycle.
Detection
-
ID:
animation-frame-budget -
Severity:
info -
What to look for: Count all animation implementations. Enumerate which use
requestAnimationFrameor CSS transforms vs.setIntervalor property-based animations. Examine animation and scroll handling code. Check for use ofrequestAnimationFrame. Look for CSS transforms and transitions vs. property-based animations (JS-driven). -
Pass criteria: Animations use
requestAnimationFrameor CSS transforms (GPU-accelerated). Frame rate stays at 60fps (16ms per frame). No jank during scrolling or animations. At least 90% of animations should use GPU-accelerated techniques (CSS transforms or requestAnimationFrame). -
Fail criteria: Animations use setInterval or property-based JS animations that block main thread. Frame rate drops below 60fps.
-
Skip (N/A) when: The application has no animations or scroll interactions.
-
Cross-reference: For paint profiling of animations, see
paint-profiling-clean. -
Detail on fail:
"Scroll listeners change layout properties per frame — main thread blocked, frame rate drops to 30fps"or"Animations use setInterval instead of requestAnimationFrame" -
Remediation: Use hardware-accelerated animations with CSS transforms or requestAnimationFrame.
/* components/animated-card.module.css — GPU-accelerated */ .card { transition: transform 0.3s ease; } .card:hover { transform: translateY(-4px); }
External references
- iso-25010:2011 · time-behaviour — Time Behaviour (performance efficiency)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-deep-dive·automated