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;
}