requestAnimationFrameJavaScript animates elements smoothly by scheduling updates right before each browser repaint using requestAnimationFrame() (rAF), or by calling element.animate() from the Web Animations API. Both approaches run smoother and drain far less battery than legacy setInterval() timers.
requestAnimationFrame() Beats setInterval()setInterval(fn, 16) runs blindly on a fixed clock even if the user switches tabs or the monitor runs at 120Hz. requestAnimationFrame(callback) automatically syncs with your display's refresh rate, passes a high-resolution timestamp, and pauses automatically in background tabs.
Animate transform (translateX, scale, rotate) and opacity instead of top or left, because transforms run on the GPU compositor without triggering expensive page layout reflows. Multiplying speed by elapsed deltaSeconds guarantees identical animation speed on both 60Hz and 120Hz screens.
const app = document.getElementById("app");
if (app) {
const box = document.createElement("div");
box.textContent = "Animated Box";
box.style.width = "120px";
box.style.padding = "8px";
app.appendChild(box);
// Web Animations API (WAAPI) runs smoothly off main-thread layout
if (typeof box.animate === "function") {
const anim = box.animate(
[
{ transform: "translateX(0px)", opacity: 0.7 },
{ transform: "translateX(120px)", opacity: 1 },
],
{ duration: 600, fill: "forwards", easing: "ease-out" }
);
console.log("WAAPI animation playState:", anim.playState);
}
}
top, left, width, or margin: Layout properties force the browser to recalculate geometry on every frame, causing visible stutter. Prefer transform: translate3d(...) and opacity.cancelAnimationFrame(rafId): Always store the ID returned by requestAnimationFrame() and cancel it when stopping an animation loop or removing the element.x += 2 per frame runs twice as fast on a 120Hz display as on a 60Hz display. Compute movement using elapsed timestamp difference.Use CSS transitions or @keyframes for standard UI hovers, modal fades, and accordions. Choose JavaScript requestAnimationFrame() when animation responds continuously to scroll, mouse drag, or game physics.
element.animate())?It is a native browser API combining CSS keyframe performance with JavaScript control methods like .pause(), .reverse(), and .finished Promises.
prefers-reduced-motion?Query window.matchMedia("(prefers-reduced-motion: reduce)").matches and skip or shorten large motion effects when true.
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.