javascriptperformancesettimeoutrequestanimationframe

Is there anything faster than setTimeout and requestAnimationFrame?


(I need a process.nextTick equivalent on browser.)

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.

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

I got about 250 with setTimeout and 70 with requestAnimationFrame in google chrome / win7. I know requestAnimationFrame goes with screen refresh rate so, how can we make this faster?

PS: I'm aware of asm.js


Solution

  • 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.