Javascript 有比setTimeout和requestAnimationFrame更快的吗?
(我需要浏览器上的process.nextTick等效项。) 我正试图充分利用javascript的性能,所以我做了一个简单的计数器。。。 在一秒钟内,我连续调用一个函数,只向变量添加一个 代码:codepen.io/rafaelcastrocouto/pen/gDFxt 在google chrome/win7中,setTimeout和requestAnimationFrame分别得到了大约250和70。 我知道requestAnimationFrame会随着屏幕刷新率而变化,所以,我们如何才能使其更快 PS:我知道asm.js很好,有一个可以立即运行代码的程序,也就是说,你可以通过Javascript 有比setTimeout和requestAnimationFrame更快的吗?,javascript,performance,settimeout,requestanimationframe,Javascript,Performance,Settimeout,Requestanimationframe,(我需要浏览器上的process.nextTick等效项。) 我正试图充分利用javascript的性能,所以我做了一个简单的计数器。。。 在一秒钟内,我连续调用一个函数,只向变量添加一个 代码:codepen.io/rafaelcastrocouto/pen/gDFxt 在google chrome/win7中,setTimeout和requestAnimationFrame分别得到了大约250和70。 我知道requestAnimationFrame会随着屏幕刷新率而变化,所以,我们如何才能
setTimeout(0)
得到它
不同之处在于setTimeout(0)
实际上不会立即运行setTimeout
被“钳制”为最小等待时间(4ms),这就是为什么您的测试程序中只有250个计数setImmediate()
但是,您可能需要检查浏览器对setImmediate
的支持,但并非所有浏览器都支持它。(当然,您可以使用setTimeout(0)
作为回退,但这样您就回到了它规定的最小等待时间)
也是一个选项,可以实现大致相同的结果,尽管它是一个更复杂的API,因为它的目的不仅仅是简单的调用循环。此外,在使用它时还需要考虑其他因素(有关更多信息,请参阅链接的MDN文章)
MDN网站还提到了使用postMessage
和其他技术将setImmediate
添加到尚不支持它的浏览器中的方法
使用requestAnimationFrame()
,测试程序应该得到60帧,因为这是每秒的标准帧数。如果你得到的不止这些,那么你的程序可能会运行超过一秒钟
使用它在计数测试中永远不会得到一个高的数字,因为它每秒只触发60次(如果硬件刷新帧速率由于某种原因较低,则触发次数会更少),但如果您的任务涉及到对显示的更新,那么这就是您所需要的,因此您可以使用requestAnimationFrame()
来限制调用它的次数,从而为程序中的其他任务释放资源
这就是存在requestAnimationFrame()
的原因。如果您关心的只是让代码尽可能频繁地运行,那么不要使用requestAnimationFrame()
;改用setTimeout
或setImmediate
。但这并不一定是性能的最佳选择,因为它会消耗浏览器执行其他任务所需的处理器功率
归根结底,性能不仅仅是让某些东西运行最大次数;这是为了让用户体验尽可能流畅。这通常意味着对调用循环施加限制。使用postMessage()
,如中所述。保持异步的最短可能延迟来自MutationObserver
,但它非常短,如果您一直调用它,UI将永远没有机会更新
所以技巧是使用MutationObserver
来增加值,同时偶尔使用requestAnimationFrame
来更新UI,但这是不允许的
看
我真的不确定这是否做了同样的事情,但是使用postMessage
:setTimeout
检查一下这个黑客,在大多数浏览器中限制为4ms,这解释了为什么你得到了250左右。@Dogbert,我在这里测试过,似乎变异观察者赢得了希望。我怀疑动画帧和帖子能赢得变异观察者,但未经测试。@rafaelcastrocouto:没问题。很乐意帮忙。(嗯,给我点分数?你能做到,你已经做到了……你把答案投了赞成票并勾选接受,除非你是指其他什么?)你应该得到一些额外的分数!gratzI注意到,requestAnimationFrame
在提到的垫片之前触发。我认为这可能发生在浏览器忙于计算时——在这种情况下,它可能更喜欢平滑的动画,而不是严格的postMessage
spec遵从性。但这只是一个假设。顺便说一句,结果来自于基于铬的electron。“此功能是非标准的,不在标准轨道上。不要在面向Web的生产站点上使用它:它不会对每个用户都有效。实现之间可能存在很大的不兼容性,将来行为可能会改变。”这是一个很好的解决方案。。。添加到笔中。。。你不喜欢这场比赛,真是卑鄙。
var div = document.createElement("div");
var count = 0;
var cur = true;
var now = Date.now();
var observer = new MutationObserver(function () {
count++;
if (Date.now() - now > 1000) {
document.getElementById("count").textContent = count;
} else {
change();
}
});
observer.observe(div, {
attributes: true,
childList: true,
characterData: true
});
function change() {
cur = !cur;
div.setAttribute("class", cur);
}
change();