raf*_*uto 14 javascript performance settimeout requestanimationframe
(我需要在浏览器上使用process.nextTick等效项.)
我正在努力充分利用javascript的性能,所以我做了一个简单的计数器...在一秒钟内我连续调用一个函数,只是将一个函数添加到变量中.
代码:codepen.io/rafaelcastrocouto/pen/gDFxt
我使用setTimeout大约250,使用google chrome/win7中的requestAnimationFrame获得70.我知道requestAnimationFrame与屏幕刷新率一致,所以我们怎样才能让它更快?
PS:我知道asm.js
Spu*_*ley 30
好吧,有setImmediate()立即运行代码,即你期望得到的代码setTimeout(0).
不同之处在于setTimeout(0)实际上并不立即运行; setTimeout被"钳制"到最小等待时间(4ms),这就是为什么你的测试程序只能得到250.setImmediate()确实可以立即运行,因此使用它可以使您的计数器测试值高出几个数量级.
但是,您可能需要检查浏览器支持setImmediate - 它在所有浏览器中都不可用.(setTimeout(0)当然,你可以用作后退,但是你会回到它施加的最短等待时间).
postMessage()也是一个选项,并且可以获得相同的结果,虽然它是一个更复杂的API,因为它的目的是为了做更多的事情,而不仅仅是一个简单的调用循环.此外,还有其他需要考虑的因素(请参阅链接的MDN文章了解更多信息).
MDN站点还提到了一个polyfill库,setImmediate其中使用了postMessage其他技术并将其添加setImmediate到不支持它的浏览器中.
有了requestAnimationFrame(),你的测试程序应该得到60,因为这是每秒的标准帧数.如果你得到的不仅仅是那个,那么你的程序可能会运行超过一秒钟.
在使用它的计数测试中你永远不会得到很高的数字,因为它只会每秒发射60次(如果硬件刷新帧速率因某种原因而降低,则更少),但如果你的任务涉及对显示的更新那就是你所需要的,所以你可以requestAnimationFrame()用来限制它被调用的次数,从而为你的程序中的其他任务释放资源.
这就是requestAnimationFrame()存在的原因.如果您关心的是尽可能多地运行代码,请不要使用requestAnimationFrame(); 使用setTimeout或setImmediate代替.但这并不一定是性能最好的东西,因为它会耗尽浏览器为其他任务所需的处理器能力.
最终,性能不仅仅是让某些东西运行最多次; 它是为了让用户体验尽可能顺畅.这通常意味着对您的呼叫循环施加限制.
仍然是异步的最短可能延迟来自MutationObserver但是如此短暂,如果你只是继续调用它,UI将永远不会有机会更新.
因此,MutationObserver在使用requestAnimationFrame偶尔更新UI时,可以使用增量值,但这是不允许的.
多么愚蠢的比赛.
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();
Run Code Online (Sandbox Code Playgroud)