是否有任何情况下setTimeout(..,0)优于requestAnimationFrame()?

时间:2017-05-26 21:14:40

标签: javascript browser

我一直在使用setTimeout(function(){ ... }, 0)作为将函数调用延迟一个tick的方法。

通常情况下,当我尝试直接操作事件循环以确保事物按特定顺序执行时,我一直在使用此方法,并且在大多数情况下,它与UI有关。

有时我会感觉到“滴答”,特别是当我使用它来运行元素上的第三方JS库时。

但我最近发现requestAnimationFrame。这几乎达到了同样的目的,但是更加优雅。

现在我很好奇,是否有任何案例,使用setTimeout(function(){ ... }, 0)requestAnimationFrame(function(){ ... })更有利?

3 个答案:

答案 0 :(得分:1)

来自https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

我看到的只有红旗是这个人:

  

运行时,回拨率可能会降低到较低的比率   背景标签或隐藏的iframe,以提高效果   和电池寿命。

但我相信只有当你有requestAnimationFrame以递归方式调用自身时才会发生。

因此,如果您有一些使用requestAnimationFrame的长时间运行代码,如果用户不在该选项卡上,则可能需要更长时间。除此之外,你正在使用一个函数来做一些从未打算做的事情,但是setTimeout并没有被设计成一种跳过勾号的方法......

作为建议: 一般来说,我发现你通常可以通过正确使用promises等来避免setTimeout技巧。但我找到了案例,尤其是。当使用Angular 1.x时我无法找到比使用它更好的解决方案。

有趣的花絮。通过简单的性能测试,requestAnimationFrame似乎要快得多:

console.time()
for(let i = 0; i < 100000; i++){
  requestAnimationFrame(() => {(5*5*77/3)*88});
}
console.timeEnd()

得到~80ms(在我的电脑上)

console.time()
for(let i = 0; i < 100000; i++){
  setTimeout(() => {(5*5*77/3)*88}, 0);
}
console.timeEnd()

得到~225ms(在我的电脑上)

答案 1 :(得分:1)

他们不是一回事。

使用setTimeout(fn, 0)调用自身的函数将尽可能多地运行。

使用requestAnimationFrame(fn)调用自身的函数将每帧调用一次 - 通常每秒60次。顾名思义,它适用于动画,在这种情况下,更新页面状态比显示它更有意义。

答案 2 :(得分:0)

视情况而定,某些情况下,例如动画requestAnimationFrame更好,而某些情况下,例如实时处理,我更喜欢setTimeout 0

为什么?因为requestAnimationFrame就像setTimeout(func, 1000/60),所以setTimeout 0更快。

但是如果您比较requestAnimationFramesetTimeout(func, 1000/60)requestAnimationFramesetTimeout更精确。