Search code examples
javascriptanimationrequestanimationframe

requestAnimationFrame processing sequence


If I have the following code:

window.requestAnimationFrame(animation1); //animation1 takes more than 16.67ms, misses the frame.
window.requestAnimationFrame(animation2); //animation2 takes 1ms to execute

Assuming animation1 and animation2 are simple color change animations, does it mean that animation2 would appear on the screen before animation1?

Or are the calls to requestAnimationFrame stacked on the browser queue, where the subsequent call will only execute when the previous call finishes?


Solution

  • TL;DR

    animation1 will always run to completion before animation2 is called, but if either of them is taking too long, the browser might not call either of them for a frame or two.


    The specification for requestAnimationFrame says:

    When the requestAnimationFrame() method is called, the user agent must run the following steps: ...

    1. Append the method's argument to document's list of animation frame callbacks, associated with document's animation frame callback identifier's current value.

    and:

    When the user agent is to run the animation frame callbacks for a Document doc with a timestamp now, it must run the following steps:

    1. Let callbacks be a list of the entries in doc's list of animation frame callbacks, in the order in which they were added to the list.

    So we can see that by running:

    window.requestAnimationFrame(animation1);
    window.requestAnimationFrame(animation2); 
    

    You are queueing up animation1 and animation2 to be called the next time "the user agent is to run the animation frame callbacks".

    That time is specified as part of the main event loop:

    1. For each fully active Document in docs, run the animation frame callbacks for that Document, passing in now as the timestamp.

    However before that, it specifies:

    1. If there is a top-level browsing context B that the user agent believes would not benefit from having its rendering updated at this time, then remove from docs all Document objects whose browsing context's top-level browsing context is B.

    That means if your callbacks are taking too long, it may decide to drop frames and not run them. However, since all requested frames are executed one after the other in step 9, you should always see the result of animation1 before animation2, but the browser may decide to drop the entire document from it's rendering loop and not call either method in the queue until a subsequent iteration through the event loop.