如果我有以下代码:

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之前运行完成,但是如果其中任何一个花费的时间太长,浏览器可能不会调用其中一个或两个帧。



requestAnimationFrameThe specification说:


  调用requestAnimationFrame()方法时,用户代理必须运行以下步骤:
  ...
  
  
  将方法的参数附加到文档的动画框架回调列表中,该列表与文档的动画框架回调标识符的当前值相关联。
  


和:


  用户代理现在要使用时间戳为文档doc运行动画帧回调时,它必须运行以下步骤:
  
  
  假设回调是doc动画帧回调列表中条目的列表,按它们添加到列表的顺序。
  


这样我们可以通过运行以下命令来查看:

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


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

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


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


但是,在此之前,它指定:


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


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

08-19 03:38