Search code examples
javascriptrequestanimationframe

Call a function each 100 milliseconds using requestAnimationFrame on chrome


I want to execute a function every 100 milliseconds. it can be done using an interval like this:

setInterval(function(){ 
console.log('done')

}, 100);

But this takes 2.5 to 3 percent CPU usage on chrome.

Now I want to do the same thing using requestAnimationFrame to test the CPU usage and compare the performances.

How can I Call a function or console log every 100 milliseconds using requestAnimationFrame on chrome?

Here is same stack question but I can't make a working code: Call a function each x second in requestAnimationFrame


Solution

  • The cost you're seeing isn't primarily setInterval's internals, it's the work to call your callback and the work your callback is doing. That's not going to change for the better with requestAnimationFrame. Much more likely it'll get worse.

    Here's how you'd do it¹, but I suspect you'll find you're better off doing what you're doing or not doing either of them:

    var last = Date.now();
    requestAnimationFrame(function tick() {
        if (Date.now() - last >= 92) { // Why 92 instead of 100? See ¹ below.
            doYourWorkHere();
    
            last = Date.now();
        }
        requestAnimationFrame(tick);
    });
    

    Note that your function is now doing at least slightly more work, and being called much more often (every ~17ms instead of every ~100ms).

    So: You're probably better off sticking with setInterval. If the CPU load of the work being done every 100ms is too high, you'll need to back off the interval.


    ¹ Why 92 instead of 100? Because each callback is about ~17ms after the last, so if you don't do your processing when it's been [say] 95ms since the last call, you won't get a chance until ~17ms later when it's been ~112ms since the last call. 92 is 100 - (17 / 2) rounded down, so at 91 you'll wait until 108, but at 92 you'll go right away. This helps you stay near every 100ms. Live example:

    var counter = 0;
    var last = Date.now();
    requestAnimationFrame(function tick() {
        let diff;
        if ((diff = Date.now() - last) >= 92) {
            console.log(`Time since last: ${diff}ms`);
    
            last = Date.now();
            ++counter;
        }
        if (counter < 20) { // Just to keep the example from running forever
          requestAnimationFrame(tick);
        }
    });
    .as-console-wrapper {
        max-height: 100% !important;
     }