requestAnimationFrame() guide

Learn the API to perform animations and schedule events in a predictable way

requestAnimationFrame()It is a relatively new browser API. It provides a more predictable way to connect the browser rendering cycle.

All current modern browsers (and IE 10+) support it.

Browser support

It is not an animation-specific API, but the most used place is animation.

JavaScript has an event loop. It runs continuously to execute JavaScript.

In the past, animation was usingsetTimeout()orsetInterval(). You perform a little animation and then callsetTimeout()Repeat this code again in a few milliseconds from now:

const performAnimation = () => {
  //...
  setTimeout(performAnimation, 1000 / 60)
}
setTimeout(performAnimation, 1000 / 60)

or

const performAnimation = () => {
  //...
}
setInterval(performAnimation, 1000 / 60)

You can stop the animation by getting the timeout or interval reference and clearing the animation:

let timer

const performAnimation = () => { //… timer = setTimeout(performAnimation, 1000 / 60) }

timer = setTimeout(performAnimation, 1000 / 60)

//… clearTimeout(timer)

This1000 / 60Interval betweenperformAnimation()The call depends on the refresh rate of the display, in most cases the refresh rate is 60 Hz (60 redraws per second), because it is useless to perform a redraw if the display cannot display it due to its limitations. In this way, we have about 16.6ms to display each frame.

The problem with this method is that even if we specify this precision accurately, the browser may still be busy performing other operations, and the setTimeout call may not be able to redraw in time, so it will be delayed until the next cycle.

This is bad because we dropped one frame and then executed the animation twice in the next frame, causing the eyes to notice the clumsy animation.

Check this example on a glitchAnimation built using setTimeout().

requestAnimationFrameIt is the standard way to perform animation. Although the code looks very similar to the setTimeout / setInterval code, the way the event is handled is very different:

let request

const performAnimation = () => { request = requestAnimationFrame(performAnimation) //animate something }

requestAnimationFrame(performAnimation)

//… cancelAnimationFrame(request) //stop the animation

This example is about glitchesAnimation built using requestAnimationFrame()Show how.

optimization

requestAnimationFrame()Because its introduction is very CPU friendly, if the current window or tab is not visible, it will cause the animation to stop.

When requestAnimationFrame() was introduced, even if the tabs were hidden, setTimeout / setInterval did run, but now because this method is also very successful in saving battery, the browser also imposes a limit on these events, with a maximum of 1 per second. Times.

userequestAnimationFrameThe browser can further optimize resource consumption and make the animation smoother.

Timeline example

If you use setTimeout or setInterval, this is the ideal timetable:

Perfect timeline

You have a set of painting (green) and rendering (purple) events, and your code is in the yellow box-by the way, these are the colors used to represent the timeline in the browser's DevTools:

The devtools timeline

The figure below shows the ideal situation. You draw and render every 60 milliseconds, and the animation is somewhere in between, completely regular.

If you use a higher frequency call for the animation function:

Too frequent timeline

Please note how we call the 4 animation steps in each frame before any rendering, which will make the animation feel very unstable.

What if setTimeout cannot run on time due to other code blocking the event loop? We ended up missing the frame:

Missed frame

What if the animation step takes longer than you expected?

Delay in the timeline

Rendering and painting events will also be delayed.

This isrequestAnimationFrame()Work intuitively:

Delay in the timeline

All animation code will runbeforeRendering and painting events. This makes the code more predictable and has a lot of time to make animations without worrying about exceeding the 16 milliseconds at our disposal.

ViewGreat video by Jake ArchibaldOn this topic.

Download mine for freeJavaScript beginner's manual


More browser tutorials: