简体   繁体   English

有什么比 setTimeout 和 requestAnimationFrame 更快的吗?

[英]Is there anything faster than setTimeout and requestAnimationFrame?

(I need a process.nextTick equivalent on browser.) (我需要浏览器上的 process.nextTick 等效项。)

I'm trying to get the most out of javascript performance so I made a simple counter ... In a second I make continuous calls to a function that just adds one to a variable.我试图最大限度地利用 javascript 性能,所以我做了一个简单的计数器......在一秒钟内,我连续调用一个函数,该函数只向变量添加一个。

The code: codepen.io/rafaelcastrocouto/pen/gDFxt代码:codepen.io/rafaelcastrocouto/pen/gDFxt

I got about 250 with setTimeout and 70 with requestAnimationFrame in google chrome / win7.我在 google chrome / win7 中使用 setTimeout 获得了大约 250 个,使用 requestAnimationFrame 获得了 70 个。 I know requestAnimationFrame goes with screen refresh rate so, how can we make this faster?我知道 requestAnimationFrame 与屏幕刷新率有关,所以我们如何使其更快?

PS: I'm aware of asm.js PS:我知道 asm.js

Well, there's setImmediate() which runs the code immediately, ie as you'd expect to get with setTimeout(0) .好吧,有setImmediate()可以立即运行代码,即正如您期望使用setTimeout(0)获得的那样。

The difference is that setTimeout(0) doesn't actually run immediately;不同之处在于setTimeout(0)实际上不会立即运行; setTimeout is "clamped" to a minimum wait time (4ms), which is why you're only getting a count of 250 in your test program. setTimeout被“限制”到最短等待时间 (4ms),这就是为什么您在测试程序中只得到 250 的计数。 setImmediate() really does run immediately, so your counter test will be orders of magnitude higher using it. setImmediate()确实会立即运行,因此您的计数器测试使用它会高setImmediate()数量级。

However you may want to check browser support for setImmediate -- it's not available yet in all browsers.但是,您可能需要检查浏览器对setImmediate支持——它还没有在所有浏览器中可用。 (you can use setTimeout(0) as a fallback of course though, but then you're back to the minimum wait time it imposes). (当然,您可以使用setTimeout(0)作为后备,但是您又回到了它强加的最短等待时间)。

postMessage() is also an option, and can achieve much the same results, although it's a more complex API as it's intended for more doing a lot more than just a simple call loop. postMessage()也是一个选项,可以实现几乎相同的结果,尽管它是一个更复杂的 API,因为它旨在做更多的事情,而不仅仅是一个简单的调用循环。 Plus there are other considerations to think of when using it (see the linked MDN article for more).此外,在使用它时还需要考虑其他注意事项(有关更多信息,请参阅链接的 MDN 文章)。

The MDN site also mentions a polyfill library for setImmediate which uses postMessage and other techniques to add setImmediate into browsers that don't support it yet. MDN 站点还提到了一个用于setImmediate库,它使用postMessage和其他技术将setImmediate添加到尚不支持它的浏览器中。

With requestAnimationFrame() , you ought to get 60 for your test program, since that's the standard number of frames per second.使用requestAnimationFrame() ,您的测试程序应该得到 60,因为这是每秒的标准帧数。 If you're getting more than that, then your program is probably running for more than an exact second.如果你得到的不止这些,那么你的程序可能运行了不止一秒。

You'll never get a high figure in your count test using it, because it only fires 60 times a second (or fewer if the hardware refresh frame-rate is lower for some reason), but if your task involves an update to the display then that's all you need, so you can use requestAnimationFrame() to limit the number of times it's called, and thus free up resources for other tasks in your program.在使用它的计数测试中,您永远不会得到很高的数字,因为它每秒仅触发 60 次(如果硬件刷新帧速率由于某种原因较低,则更少),但如果您的任务涉及更新显示那么这就是你所需要的,所以你可以使用requestAnimationFrame()来限制它被调用的次数,从而为你的程序中的其他任务释放资源。

This is why requestAnimationFrame() exists.这就是requestAnimationFrame()存在的原因。 If all you care about is getting your code to run as often as possible then don't use requestAnimationFrame() ;如果你关心的只是让你的代码尽可能频繁地运行,那么不要使用requestAnimationFrame() use setTimeout or setImmediate instead.使用setTimeoutsetImmediate代替。 But that's not necessarily the best thing for performance, because it will eat up the processor power that the browser needs for other tasks.但这对性能来说不一定是最好的,因为它会消耗浏览器执行其他任务所需的处理器能力。

Ultimately, performance isn't just about getting something to run the maximum number of times;归根结底,性能不仅仅是让某些东西运行最大次数; it's about making the user experience as smooth as possible.这是为了让用户体验尽可能流畅。 And that often means imposing limits on your call loops.这通常意味着对您的呼叫循环施加限制。

Shortest possible delay while still being asynchronous is from MutationObserver but it is so short that if you just keep calling it, the UI will never have chance to update.仍然是异步的最短可能延迟来自MutationObserver但它太短了,如果你继续调用它,UI 将永远没有机会更新。

So trick would be to use MutationObserver to increment value while using requestAnimationFrame once in a while to update UI but that is not allowed.所以技巧是使用MutationObserver来增加值,同时偶尔使用requestAnimationFrame来更新 UI,但这是不允许的。

See http://jsfiddle.net/6TZ9J/1/http://jsfiddle.net/6TZ9J/1/

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();

本博客所述使用postMessage()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 requestAnimationFrame 比 setInterval 或 setTimeout 更好 - Why is requestAnimationFrame better than setInterval or setTimeout 是否有任何情况下setTimeout(..,0)优于requestAnimationFrame()? - Is there any case where setTimeout(.., 0) is better than requestAnimationFrame()? requestAnimationFrame 仅在需要时运行动画比一直使用 requestAnimationFrame 快得多 - requestAnimationFrame only when needed runs the animation much faster than having requestAnimationFrame all the time JavaScript-setTimeout和requestAnimationFrame中的“ this” - JavaScript - 'this' inside setTimeout and requestAnimationFrame 卡在SetInterval,SetTimeOut和Requestanimationframe中 - Stuck with SetInterval ,SetTimeOut and Requestanimationframe 用 requestAnimationFrame() 替换 setTimeout() - Replacing setTimeout() with requestAnimationFrame() 如何比javascript中的短setTimeout更快? - How to go faster than a short setTimeout in javascript? setTimeout的执行速度比同时setInterval的执行速度快 - setTimeout executes faster than simultaneous setInterval 节点js,为什么setTimeout用50ms比setTimeout 0快 - Node js, why is setTimeout with 50ms is faster than setTimeout 0 setTimeout中带有requestAnimationFrame的控制台错误 - console error during setTimeout with requestAnimationFrame
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM