Prashant Prashant - 2 months ago 14
Javascript Question

Request animation frame called constantly

Trying to understand RequestAnimationFrame and how it works internally.

Browser has a main thread which is an event loop. The event loop can be populated with various asynchronous events like user interaction, timers getting fired, network calls completing and events triggering layout and painting e.g. input or JS.

So, when a JS function invalidates the layout of the DOM or causes repaint, the browser's main thread repaints the layers that need updating and the compositor thread uploads the updated textures to the GPU where final compositing occurs and the resulting image is displayed onto the screen.

So, I have the impression that browsers only perform paint when actually required. If you capture events on Chrome Dev Tools timeline on a static page with nothing happening, absolutely no events are captured (no layout, no paint, no animation frame fired). Makes sense.

But then you run the following code on the console,

function onBeforeNextRepaint() {
requestAnimationFrame(onBeforeNextRepaint);

console.log('About to paint ...');
}

onBeforeNextRepaint();


Now, you capture the timeline events again and you notice the 'Animation Frame Fired' events and your console gets logged with 'About to paint ...'.

onBeforeNextRepaint gets called

Animation Frame Fired invoked

According to MDN,


The Window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint.


That means the browser is constantly painting and therefore calling my function to log the message before each repaint. I am guessing the browsers maintain a scheduler that makes the paint calls at the rate that matches the refresh rate of the screen.

Now my confusion lies on the following:


  1. Is the browser's main thread constantly repainting, generating textures and uploading textures to the GPU and making draw calls (throttled to match the refresh rate of the screen)? (Sounds inefficient)

  2. Is that the reason why my 'onBeforeNextRepaint' callback gets called constantly?

  3. If 1 and 2 are true, on my first timeline capture, why do i not capture 'Update Layer Trees' and 'Composite Layers' events?


Answer

I think you are misunderstanding the description given by MDN. Let me break it down.

The Window.requestAnimationFrame() method tells the browser that you wish to perform an animation

This means it will tell the browser that you wish to preform an animation that will require repainting. But to do that, we are going to need to run some code.

and requests that the browser call a specified function to update an animation before the next repaint.

This means that just before the next repaint, which the animation would require, call my callback function.

requestAnimationFrame is not a paint event callback, but a means of firing a callback before the next paint which the browsers must now preform.

Comments