Skip to main content
deleted 72 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Alternative to setInterval and setTimeout

JavaScript's setTimeout() and setInterval() are evil and not precise...:

  1. Both functions have a delay of a varying quantity of milliseconds.

    Please see: https://andrewduthieBoth functions have a delay of a varying quantity of milliseconds.com/2013/12/31/creating-a-self-correcting-alternative-to-javascripts-setinterval/

  2. 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().

So I wrote these functions: This makes it the perfect substitute for a modern setTimeout() and setInterval().

RafTimeoutRafTimeout

RafIntervalRafInterval

http://jsfiddle.net/wZ9Z6/jsFiddle

QUESTIONSQuestions

ifIf the code above does not work here is the original code.:

Alternative to setInterval and setTimeout

JavaScript's setTimeout() and setInterval() are evil and not precise...

  1. Both functions have a delay of a varying quantity of milliseconds.

    Please see: https://andrewduthie.com/2013/12/31/creating-a-self-correcting-alternative-to-javascripts-setinterval/

  2. 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().

So I wrote these functions:

RafTimeout

RafInterval

http://jsfiddle.net/wZ9Z6/

QUESTIONS

if the code above does not work here is the original code.

JavaScript's setTimeout() and setInterval() are evil and not precise:

  1. Both functions have a delay of a varying quantity of milliseconds.

  2. 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().

RafTimeout

RafInterval

jsFiddle

Questions

If the code above does not work here is the original code:

JavaScript's setTimeout() and setInterval() are evil and not precise...

  1. bothBoth functions have a delay of variousa varying quantity of milliseconds http://www.andrewduthie.com/post/a-self-correcting-setinterval-alternative/.

    Please see: https://andrewduthie.com/2013/12/31/creating-a-self-correcting-alternative-to-javascripts-setinterval/

  2. bothBoth functions are very resource intensive as-intensive because they execute several times every second.

A new alternative is window.requestAnimationFrame(). it's, which is less resource=intensiveresource-intensive, disabled on page blur, and does not slow down other stuff and it is disabled on page blur.

This makes it the perfect substitute for a modern setTimeout() and setInterval().

So I wrote thisthese functions:

ThisThese functions use requestAnimationframe() to check if the time ishas 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-intensive. Another advantage/disadvantage  (dependsor disadvantage) is that the functions are not executed on page blur.

  1. 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 thisthese time-based functions?

  2. Is there a better solution to clear those functions?

  3. 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 areis just one requestAnimationframe or multiple). So how do the browsers handle those multiple requestAnimationframes()?

JavaScript's setTimeout and setInterval are evil and not precise...

  1. both have a delay of various milliseconds http://www.andrewduthie.com/post/a-self-correcting-setinterval-alternative/

  2. both are very resource intensive as they execute several times every second.

A new alternative is requestAnimationFrame. it's less resource=intensive, does not slow down other stuff and it is disabled on page blur.

This makes it the perfect substitute for a modern setTimeout and setInterval.

So I wrote this functions:

This functions use requestAnimationframe to check if the time is 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/disadvantage(depends) is that the functions are not executed on page blur.

  1. 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 this time-based functions?

  2. Is there a better solution to clear those functions?

  3. For heavy animations and multiple intervals, timeouts I was thinking to activate a single requestAnimationFrame loop which check for intervals and timeouts inside a previously stored array... (but I think there should be no difference if there are just one requestAnimationframe or multiple). So how do the browsers handle those multiple requestAnimationframes?

JavaScript's setTimeout() and setInterval() are evil and not precise...

  1. Both functions have a delay of a varying quantity of milliseconds.

    Please see: https://andrewduthie.com/2013/12/31/creating-a-self-correcting-alternative-to-javascripts-setinterval/

  2. 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().

So I wrote these functions:

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.

  1. 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?

  2. Is there a better solution to clear those functions?

  3. 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 one requestAnimationframe or multiple). So how do the browsers handle those multiple requestAnimationframes()?

Rollback to Revision 3
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

EDIT 1: New version with namespace & single raF

  1. Custom Namespace
  2. one Single raF controls all timers
  3. the timer index is reset to 0
  4. every resource-intensive function or nested variable is cached
  5. all functions are just references
  6. theoretically the max delay is 17ms
  7. uses bitwise & short hand operators to increase performance

I tested 10000 timers in 5sec and it worked without slowdown.

The loop run at stable 17ms==60fps==60HZ.

And The maximum delay was around 10ms.

;(function(ns){

 var index=0, // increases or uid until there are no more timers then set to 0
     timers=[], // contains all timers
     L=0, // static timers.length (increases performance)
     now=Date.now, // shortcut
     raf=window.requestAnimationFrame, // shortcut
     test=0; // variable to calculate the average update time in ms

 function globalTimer(){ // the global timing function
  var l=L,n=now(),t;
  l>0?raf(globalTimer):
  (
   index=0,
   test=0,
   console.log(
    'Stopping Global Timer and Setting Global Index To '+
    index+', also test to '+test
   )
  );
  while(l--){
   t=timers[l];//t=[index,callback,delay,offset,startTime]
   n-t[3]<t[2]||
   (
    //t[3]+=t[2], // this is for the setInterval function
    t[1](),
    timers.splice(l,1),
    L=timers.length,
    console.log([
     'Delay Set: ',t[2],
     ' - Time Passed: ',n-t[4],
     ' - Update every: ',(n-t[4])/test,'ms'
    ].join(''))
   );
  }
  test++
 }

 ns.setTimeout=function(cb,delay){
  var i=index++,n=now();
  L||(raf(globalTimer),console.log('Executing Global Timer'));
  L=timers.push([i,cb,delay,n,n]);
  return i
 }

 ns.clearTimeout=function(i){
  var l=L;
  while(l--){
   timers[l][0]!=i||(timers.splice(l,1))
  }
 }

 /*ns.setInterval=function(callback,delay){...}
 ns.clearInterval=function(callback,delay){...}*/

}(this.Timers=this.Timers||{}));

Usage

var T1=Timers.setTimeout(function(){console.log('new timer')},3000);
Timers.clearTimeout(T1);

So basically i tried to put less possible calculations inside the globaltimer function. even if i could put the cleartimeout index check inside the globaltimer i created a distinct while loop.but i'm not shure if it's better or not.(atm i'm thinking of some sort of indexof...)

Demo

http://jsfiddle.net/G34Sr/


EDIT 1: New version with namespace & single raF

  1. Custom Namespace
  2. one Single raF controls all timers
  3. the timer index is reset to 0
  4. every resource-intensive function or nested variable is cached
  5. all functions are just references
  6. theoretically the max delay is 17ms
  7. uses bitwise & short hand operators to increase performance

I tested 10000 timers in 5sec and it worked without slowdown.

The loop run at stable 17ms==60fps==60HZ.

And The maximum delay was around 10ms.

;(function(ns){

 var index=0, // increases or uid until there are no more timers then set to 0
     timers=[], // contains all timers
     L=0, // static timers.length (increases performance)
     now=Date.now, // shortcut
     raf=window.requestAnimationFrame, // shortcut
     test=0; // variable to calculate the average update time in ms

 function globalTimer(){ // the global timing function
  var l=L,n=now(),t;
  l>0?raf(globalTimer):
  (
   index=0,
   test=0,
   console.log(
    'Stopping Global Timer and Setting Global Index To '+
    index+', also test to '+test
   )
  );
  while(l--){
   t=timers[l];//t=[index,callback,delay,offset,startTime]
   n-t[3]<t[2]||
   (
    //t[3]+=t[2], // this is for the setInterval function
    t[1](),
    timers.splice(l,1),
    L=timers.length,
    console.log([
     'Delay Set: ',t[2],
     ' - Time Passed: ',n-t[4],
     ' - Update every: ',(n-t[4])/test,'ms'
    ].join(''))
   );
  }
  test++
 }

 ns.setTimeout=function(cb,delay){
  var i=index++,n=now();
  L||(raf(globalTimer),console.log('Executing Global Timer'));
  L=timers.push([i,cb,delay,n,n]);
  return i
 }

 ns.clearTimeout=function(i){
  var l=L;
  while(l--){
   timers[l][0]!=i||(timers.splice(l,1))
  }
 }

 /*ns.setInterval=function(callback,delay){...}
 ns.clearInterval=function(callback,delay){...}*/

}(this.Timers=this.Timers||{}));

Usage

var T1=Timers.setTimeout(function(){console.log('new timer')},3000);
Timers.clearTimeout(T1);

So basically i tried to put less possible calculations inside the globaltimer function. even if i could put the cleartimeout index check inside the globaltimer i created a distinct while loop.but i'm not shure if it's better or not.(atm i'm thinking of some sort of indexof...)

Demo

http://jsfiddle.net/G34Sr/

added 42 characters in body
Source Link
cocco
  • 303
  • 1
  • 3
  • 12
Loading
added 2595 characters in body
Source Link
cocco
  • 303
  • 1
  • 3
  • 12
Loading
added 17 characters in body; edited tags; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Loading
Source Link
cocco
  • 303
  • 1
  • 3
  • 12
Loading