requestAnimationFrame处理顺序

Meg*_*ear 3 javascript animation requestanimationframe

如果我有以下代码:

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

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

或者调用是否requestAnimationFrame堆积在浏览器队列中,只有在前一个调用完成后才会执行后续调用?

Jam*_*rpe 5

长话短说

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


规范requestAnimationFrame

当调用 requestAnimationFrame() 方法时,用户代理必须运行以下步骤:...

  1. 将该方法的参数附加到文档的动画帧回调列表,与文档的动画帧回调标识符的当前值关联。

和:

当用户代理现在要为带有时间戳的文档文档运行动画帧回调时,它必须运行以下步骤:

  1. 令回调为文档动画帧回调列表中的条目列表,按照它们添加到列表的顺序排列。

所以我们可以通过运行看到:

window.requestAnimationFrame(animation1);
window.requestAnimationFrame(animation2); 
Run Code Online (Sandbox Code Playgroud)

您正在排队animation1,并animation2在下次“用户代理运行动画帧回调”时被调用。

该时间被指定为主事件循环的一部分:

  1. 对于文档中的每个完全活动的文档,运行该文档的动画帧回调,现在作为时间戳传入。

但在此之前,它指定:

  1. 如果存在用户代理认为此时更新其渲染不会受益的顶级浏览上下文 B,则从文档中删除其浏览上下文的顶级浏览上下文为 B 的所有 Document 对象。

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