RequestAnimationFrame at the beginning or end of a function?

If I have a loop using requestAnimationFrame, like this:

function render() { // Rendering code requestAnimationFrame(render); } 

Will there be any difference if I put requestAnimationFrame at the beginning of the function, for example:

 function render() { requestAnimationFrame(render); // Rendering code } 

I did not notice any difference, but I saw both implementations, is one of them better anyway or are they the same?

Edit: One thing that I thought of is that if I put it at the beginning and the rendering code would take quite a while, say 10 ms, wouldn't I put it at the end to reduce the frame rate from 10 ms?

+8
javascript requestanimationframe
source share
4 answers

requestAnimationFrame always calls its callback asynchronously, so as long as your rendering code is synchronous and throws no exceptions, it doesn't make any difference.

It’s essentially a style choice, choose for yourself which approach is cleaner. Introducing it at the top, we can emphasize that render plans itself and does it even if there are errors in the rendering. Entering it at the bottom allows you to conditionally break out of the rendering cycle (for example, when you want to pause the game).

+7
source share

This probably will not change the situation. The requestAnimationFrame method is asynchronous, so anyway, your rendering function will work as expected. But ... there is a trick when it comes to stopping. Say you have the following code:

 function render() { requestAnimationFrame(render); // Rendering code } 

To stop the next rendering, you need to call the cancelAnimationFrame method, for example:

 function render() { requestAnimationFrame(render); // Rendering code if (noLongerInterested) { cancelAnimationFrame(); } } 

Otherwise, the render method will run indefinitely. Alternatively, you can:

 function render() { // Rendering code if (stillInterested) { requestAnimationFrame(render); } } 

As for dropping frames, you can look at requestAnimationFrame as a fixed schedule (at 60 frames per second, this will be about 16 ms intervals). If your code takes longer, the browser will begin to drop frames. See Patrick Roberts answer for instructions on how to take responsibility for your frames and use them for more consistent rendering.

I hope this helps!

+2
source share

To answer your question, these two functions will affect the time during which the asynchronous callback is executed only if your rendering code is longer than the speed of the animation frame (usually about 16 - 33 ms depending on the browser implementation). However, if you used this API on your own, even this should not change.

Please note that you refuse to use the optional parameter passed from requestAnimationFrame - timestamp .

Remember to calculate your deltas if you have deltas-dependent animations for rendering. Typically, you multiply the "speed" animation with the delta timestamp (current timestamp minus the previous timestamp ) to get the effective distance that the object should move around the screen. Its effect is especially noticeable when your rendering code does not take the same amount of time to execute each frame.

Demo

 var untimed = 20; var timed = 20; function untimedRender() { var then = performance.now() + Math.random() * 100; while (performance.now() < then) {} // estimated velocity untimed += 50 / 30; document.querySelector('#untimed').style.left = Math.min(Math.floor(untimed), 200) + 'px'; if (untimed < 200) { requestAnimationFrame(untimedRender); } else { last = performance.now(); requestAnimationFrame(timedRender); } } var last; function timedRender(timestamp) { var delta = timestamp - last; var then = timestamp + Math.random() * 100; last = timestamp; while (performance.now() < then) {} // calculated velocity timed += delta / 30; document.querySelector('#timed').style.left = Math.min(Math.floor(timed), 200) + 'px'; if (timed < 200) { requestAnimationFrame(timedRender); } } requestAnimationFrame(untimedRender); 
 div { position: absolute; left: 20px; width: 10px; height: 10px; } #untimed { background-color: #F00; top: 20px; } #timed { background-color: #00F; top: 50px; } 
 <div id="untimed"></div> <div id="timed"></div> 

Notice how the blue square seems to support a more consistent speed overall. That is the intention.

+1
source share

MDN 's description states that:

The window.requestAnimationFrame () method tells the browser that you want to perform the animation, and asks the browser to call the specified function to update the animation before the next redraw.

When it redraws, it pretty much depends on the browser. There should be no difference in behavior if your JS is still working when the redraw occurred.

The WhatWG specification does not mention the expectation that the JS call stack will be cleared or something like that, although an exceptionally long-lasting function will block the user interface stream and, therefore, prevent animation frames from being called.

-one
source share

All Articles