If I’m doing multiple animations, is it OK performance-wise to add multiple requestAnimationFrame
callbacks? F.ex:
function anim1() { // animate element 1 } function anim2() { // animate element 2 } function anim3() { // animate element 3 } requestAnimationFrame(anim1); requestAnimationFrame(anim2); requestAnimationFrame(anim3);
Or is it proven worse than using a single callback:
(function anim() { requestAnimationFrame(anim); anim1(); anim2(); anim3(); }());
I’m asking because I don’t really know what is going on behind the scenes, is requestAnimationFrame
queuing callbacks when you call it multiple times?
You should be using only one requestAnimationFrame call as calls to requestAnimationFrame do stack.
With requestAnimationFrame, your frame rate is typically around 60 frames per second (FPS). To repeat that differently, this means your requestAnimationFrame function and related code have the potential to refresh your screen 60 times every second.
The requestAnimationFrame() method only runs once. You can make it loop over-and-over again using a technique called recursion. Let's say you wanted to count from 0 up to 500, and update the UI each time.
requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser calls a specified function to update an animation before the next repaint. The method takes a callback as an argument to be invoked before the repaint.
I don't think any of these answers really explained what I was looking for: "do n calls to requestAnimationFrame" get debounced (i.e. dequeued 1 per frame) or all get invoked in the next frame.
When callbacks queued by requestAnimationFrame() begin to fire multiple callbacks in a single frame (mdn)
This suggests the latter, multiple callbacks can be invoked in the same frame.
I confirmed with the following test. A 60 hz refresh rate translates to a 17ms period. If it were the former, no 2 timestamps would be within 17ms of each other, but that was not the case.
let sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); let update = async timestamp => { console.log('update called', timestamp) await sleep(10); requestAnimationFrame(update); } requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update); requestAnimationFrame(update);
You should be using only one requestAnimationFrame
call as calls to requestAnimationFrame
do stack. The single callback version is thus more performant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With