JavaScript's setTimeout() and setInterval() are evil and not precise:
Both functions have a delay of a varying quantity of milliseconds.
Both functions are very resource-intensive because they execute several times every second.
A new alternative is window.requestAnimationFrame(), which is less resource-intensive, disabled on page blur, and does not slow down other stuff. This makes it the perfect substitute for a modern setTimeout() and setInterval().
Description
These functions use requestAnimationframe() to check if the time has passed
based on the elapsed Time calculated from Date.now(). The time passed is more precise than the native functions and theoretically less resource-intensive. Another advantage (or disadvantage) is that the functions are not executed on page blur.
Good for: animations, visual effects
Bad for: timers, clock
RafTimeout
window.rtimeOut=function(callback,delay){
var dateNow=Date.now,
requestAnimation=window.requestAnimationFrame,
start=dateNow(),
stop,
timeoutFunc=function(){
dateNow()-start<delay?stop||requestAnimation(timeoutFunc):callback()
};
requestAnimation(timeoutFunc);
return{
clear:function(){stop=1}
}
}
RafInterval
window.rInterval=function(callback,delay){
var dateNow=Date.now,
requestAnimation=window.requestAnimationFrame,
start=dateNow(),
stop,
intervalFunc=function(){
dateNow()-start<delay||(start+=delay,callback());
stop||requestAnimation(intervalFunc)
}
requestAnimation(intervalFunc);
return{
clear:function(){stop=1}
}
}
Usage
var interval1,timeout1;
window.onload=function(){
interval1=window.rInterval(function(){console.log('interval1')},2000);
timeout1=window.rtimeOut(function(){console.log('timeout1')},5000);
}
/* to clear
interval1.clear();
timeout1.clear();
*/
Demo
Questions
Normally I don't write functions inside functions, but in this case it's probably a good solution. What about memory leaks if I create hundreds of these time-based functions?
Is there a better solution to clear those functions?
For heavy animations and multiple intervals and timeouts, I was thinking to activate a single
requestAnimationFrame()loop which would check for intervals and timeouts inside a previously stored array... (but I think there should be no difference if there is just onerequestAnimationframeor multiple). So how do the browsers handle those multiplerequestAnimationframes()?
Note:
If the code above does not work here is the original code:
window.rInterval=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b||(e+=b,a());f||d(g)};d(g);return{clear:function(){f=1}}}//callback,delay
window.rtimeOut=function(a,b){var c=Date.now,d=window.requestAnimationFrame,e=c(),f,g=function(){c()-e<b?f||d(g):a()};d(g);return{clear:function(){f=1}}}
requestAnimationFrameis called on average 60 times per second.. At first sight, your code is far eviler. \$\endgroup\$setTimeoutchecks more often, that is the first I hear of that \$\endgroup\$requestAnimation10 times, it would have executedsetTimeoutonce, right ? \$\endgroup\$