patternjavascriptModerate
requestAnimationFrame: The Correct Way to Run JS Animations
Viewed 0 times
requestAnimationFramerAFanimation loopsmooth animationDOMHighResTimeStampcancel animation frame
Problem
Using
setInterval or setTimeout for animation causes jank because they are not synchronized with the browser's paint cycle.Solution
Use
requestAnimationFrame (rAF) to schedule animation work. The browser calls the callback just before each paint, providing a DOMHighResTimeStamp for time-based interpolation.function animateBox(element) {
let start = null;
const duration = 600;
function step(timestamp) {
if (!start) start = timestamp;
const elapsed = timestamp - start;
const progress = Math.min(elapsed / duration, 1);
const ease = 1 - Math.pow(1 - progress, 3); // easeOutCubic
element.style.transform = `translateX(${ease * 200}px)`;
if (progress < 1) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// Cancel when done
const id = requestAnimationFrame(step);
cancelAnimationFrame(id);Why
rAF is synchronized with the display refresh rate (typically 60Hz or 120Hz).
setInterval(fn, 16) fires independently, causing frames to be skipped or doubled depending on timer drift.Gotchas
- Always use the
timestampargument for elapsed time — do not computeDate.now()inside the callback, which adds overhead. - Store the rAF id and call
cancelAnimationFrameon component unmount to prevent memory leaks. - rAF callbacks are paused by the browser when the tab is hidden, saving battery.
- For complex animations, prefer CSS or a library (GSAP, Framer Motion) over manual rAF loops.
Revisions (0)
No revisions yet.