requestAnimationFrame vs CSS AnimationsDynamic web animations can be driven by CSS transitions, CSS @keyframes, or JavaScript loops. For high-performance 60fps JavaScript animations, window.requestAnimationFrame() syncs frame rendering with browser screen refresh rates.
flowchart TD
AnimType["Animation Architecture"] --> CSSAnim["CSS Transitions / Keyframes (GPU-Accelerated)"]
AnimType --> RAF["requestAnimationFrame() (60fps JS Engine Loop)"]
AnimType --> LegacyTimer["setInterval / setTimeout (Un-synced / Laggy)"]
| Method | FPS Synchronization | Pauses in Background Tabs? | Best Use Case |
|---|---|---|---|
| CSS Transitions / Keyframes | Hardware Accelerated (GPU) | Yes | UI hover effects, simple transforms. |
requestAnimationFrame() |
Synced to Monitor Hz (60-144fps) | Yes (Conserves battery & CPU) | Canvas games, complex JS physics. |
setInterval() |
Un-synced | No (Runs continuously) | Do not use for animation. |
// Demonstrating 60fps Animation Loop with requestAnimationFrame
document.addEventListener("DOMContentLoaded", () => {
const box = document.createElement("div");
box.style.width = "50px";
box.style.height = "50px";
box.style.backgroundColor = "#ef4444";
box.style.position = "absolute";
box.style.top = "100px";
box.style.left = "0px";
document.body.appendChild(box);
let posX = 0;
let animationFrameId = null;
// Smooth Animation Loop
function animate(timestamp) {
posX += 2; // Move 2px per frame
box.style.left = `${posX}px`;
if (posX < 300) {
// Schedule next frame
animationFrameId = requestAnimationFrame(animate);
} else {
console.log("Animation Complete!");
cancelAnimationFrame(animationFrameId);
}
}
// Start Animation
animationFrameId = requestAnimationFrame(animate);
});
setInterval for Animations: setInterval fires regardless of browser layout state, causing dropped frames and high CPU usage.transform and opacity: Animate CSS properties like transform: translateX() and opacity because they trigger fast GPU compositor threads without causing expensive DOM layout reflows.requestAnimationFrame() and call cancelAnimationFrame(id) when unmounting or stopping animations.Why does animating transform: translateX(100px) perform better than animating left: 100px?
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.