Currently, I am rendering WebGL content using requestAnimationFrame which runs at (ideally) 60 FPS. I’m also concurrently scheduling an “update” process, which handles AI, physics, and so on using setTimeout. I use the latter because I only really need to update objects roughly 30 times per second, and it’s not really part of the draw sequence; it seemed like a good idea to save the remaining CPU for actual render passes, since most of my animations are fairly hardware intensive.
My question is one of best practices. setTimeout and setInterval are not particularly kind to battery life and CPU consumption, especially when the browser is not in focus. On the other hand, using requestAnimationFrame (or tying the updates directly into the existing render phase) will potentially enforce far more updates every second than are strictly necessary, and may stop updating altogether when the browser is not in focus or at other times the browser deems unnecessary for “animation”.
What is the best course of action for updating, but not rendering content?
Let’s be honest: Neither is
requestAnimationFrame. The difference is that RAF automatically turns off when you leave the tab. That behavior can be emulated withsetTimeoutif you use the Page Visibility API, though, so in reality the power consumption problems between the two are about on par if used intelligently.Beyond that, though,
setTimeout\Intervalis perfectly appropriate for use in your case. The only thing that you may want to be aware of is that you’ll be hard pressed to get it perfectly in sync with the render loop. You’ll have cases where you may draw one too many times before your animation update hits, which can lead to minor stuttering. If you’re rendering at 60hz and updating at 30hz it shouldn’t be a big issue, but you’ll want to be aware of it.If staying perfectly in sync with the render loop is important to you, you could simply have a
if(framecount % 2) { updateLogic(); }at the top of your RAF callback, which effectively limits your updates to 30hz (every other frame) and it’s always in sync with the draw.