什么浏览器内部操作阻止调用requestAnimationFrame?

时间:2013-06-18 22:14:07

标签: javascript html5 performance dom cross-browser

我理解这个问题的答案是特定的浏览器(甚至浏览器版本),但我希望可能存在一些适用于所有地方的一般规则或行为。

我知道我的JavaScript在requestAnimationFrame回调中的执行时间会降低调用率。但是我的代码影响但不一定控制的浏览器活动的其余部分呢?我的DOM更改引起的所有重排,布局和绘制活动是否在后续调用requestAnimationFrame回调之前同步发生?或者是否有可能在之前的更改像素在屏幕上显示之前调用下一个回调?

2 个答案:

答案 0 :(得分:1)

通常,浏览器需要做的一切,重绘,处理setTimeout和setInterval都是事件队列中的事件并逐个执行。

requestAnimationFrame是一种特殊情况,因为它与监视器上的VBLANK间隙同步,这意味着当VBLANK发生时将调用回调。

正如他在回答中所说的那样,Javascript是单线程的,因此是事件队列,但在这种情况下,浏览器会强制事件转发(超前于当前队列)。

回调的确切结果是,当前绘制到画布的所有内容都“浏览”到浏览器的位图(您在屏幕上看到的内容),然后继续使用该功能。无论其他事件的结果是什么,此时也会更新(即使它们处于进展中 - 内部元素被处理为自己的位图,然后作为画布元素IIRC被绘制到屏幕上。)

即使回调发生时它应该并不意味着例如在回调函数本身的调用之间不会发生绘制事件。这当然会影响表现。

接下来的事情是从第0帧到第1帧你有时间预算,通常是16.7毫秒左右(@ 60Hz)。如果您的任务未在此预算范围内完成,则不会发生任何事情,但是当您致电requestAnimationFrame时,它将不会回调,直到下一次VBLANK发生(“跳过心跳”)并且您会注意到这是动画中的混蛋(如您将看到setTimeout / setInternval,因为它们不会同步到VBLANK,并且会不时地在更新之间产生混乱 - 这是requestAnimationFrame与其更低级别构造一起提供的主要原因使其本身更具性能。)

当标签处于非活动状态(或者存在硬件限制或电池运行时),

requestAnimationFrame回调率降低到一半(在浏览器中似乎是一致的)。不同之处在于现在事件不是每隔~16.7毫秒强制一次,而是在~33.4毫秒,其他事件像以前一样执行(重新绘制等)(不确定供应商是否已采用减慢事件队列的速度,尽管)。

答案 1 :(得分:0)

JavaScript(在浏览器中)是单线程的,所以一切都按顺序发生。从这个角度来看,一切都会影响一切。但是只要这些操作花费的时间少于一个框架(并且希望他们愿意),你就不应该担心它。

其中一个好处是您不必担心同步。在之前的回调完成之前,下一次调用不会发生。