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)
假设animation1
和animation2
是简单的颜色变化动画,这是否意味着animation2
之前会出现在屏幕上animation1
?
或者调用是否requestAnimationFrame
堆积在浏览器队列中,只有在前一个调用完成后才会执行后续调用?
长话短说
animation1
总是会在调用之前运行完成animation2
,但如果其中任何一个花费的时间太长,浏览器可能不会在一两帧内调用它们中的任何一个。
规范说requestAnimationFrame
:
当调用 requestAnimationFrame() 方法时,用户代理必须运行以下步骤:...
- 将该方法的参数附加到文档的动画帧回调列表,与文档的动画帧回调标识符的当前值关联。
和:
当用户代理现在要为带有时间戳的文档文档运行动画帧回调时,它必须运行以下步骤:
- 令回调为文档动画帧回调列表中的条目列表,按照它们添加到列表的顺序排列。
所以我们可以通过运行看到:
window.requestAnimationFrame(animation1);
window.requestAnimationFrame(animation2);
Run Code Online (Sandbox Code Playgroud)
您正在排队animation1
,并animation2
在下次“用户代理运行动画帧回调”时被调用。
该时间被指定为主事件循环的一部分:
- 对于文档中的每个完全活动的文档,运行该文档的动画帧回调,现在作为时间戳传入。
但在此之前,它指定:
- 如果存在用户代理认为此时更新其渲染不会受益的顶级浏览上下文 B,则从文档中删除其浏览上下文的顶级浏览上下文为 B 的所有 Document 对象。
这意味着如果您的回调花费的时间太长,它可能会决定丢弃帧而不运行它们。但是,由于在步骤 9 中所有请求的帧都是一个接一个执行的,因此您应该始终animation1
看到before的结果animation2
,但浏览器可能会决定从其渲染循环中删除整个文档,并且不会调用队列中的任一方法,直到后续调用通过事件循环进行迭代。