requestAnimationFrame 处理顺序

requestAnimationFrame processing sequence

如果我有以下代码:

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

假设animation1animation2是简单的颜色变化动画,是否意味着animation2会在animation1之前出现在屏幕上?

或者对 requestAnimationFrame 的调用是否堆叠在浏览器队列中,后续调用仅在前一个调用完成时执行?

TL;DR

animation1 总是会在调用 animation2 之前 运行 完成,但是如果它们中的任何一个花费的时间太长,浏览器可能不会在一两帧内调用它们中的任何一个.


The specification 对于 requestAnimationFrame 说:

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.

和:

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.

所以我们可以看到 运行ning:

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

您正在排队 animation1animation2 等待下次呼叫 "the user agent is to run the animation frame callbacks".

那个时间 is specified 作为主事件循环的一部分:

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

然而在此之前,它指定:

  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.

这意味着如果您的回调花费的时间太长,它可能会决定丢帧而不是 运行 它们。但是,由于所有请求的帧都是在第 9 步中一个接一个地执行的,所以你应该 总是animation2 之前看到 animation1 的结果,但是浏览器 可能决定从它的呈现循环中删除整个文档并且不调用队列中的任何一个方法,直到通过事件循环进行后续迭代。