Is there anything faster than setTimeout and requestAnimationFrame?
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.
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.
See 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();
Well, there's setImmediate()
which runs the code immediately, ie as you'd expect to get with setTimeout(0)
.
The difference is that setTimeout(0)
doesn't actually run immediately; setTimeout
is "clamped" to a minimum wait time (4ms), which is why you're only getting a count of 250 in your test program. setImmediate()
really does run immediately, so your counter test will be orders of magnitude higher using it.
However you may want to check browser support for setImmediate
-- it's not available yet in all browsers. (you can use setTimeout(0)
as a fallback of course though, but then you're back to the minimum wait time it imposes).
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. Plus there are other considerations to think of when using it (see the linked MDN article for more).
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.
With requestAnimationFrame()
, you ought to get 60 for your test program, since that's the standard number of frames per second. 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.
This is why requestAnimationFrame()
exists. If all you care about is getting your code to run as often as possible then don't use requestAnimationFrame()
; use setTimeout
or setImmediate
instead. 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.