javascript - How do browsers determine what time setInterval should use? -


it seem in general, browsers in cases modify, beyond minimum clamp, actual time interval setinterval uses. instance, have following code:

function start() { window.setinterval(function() { update(); }, 1); } lasttime = new date; numframes = 0; lastframes = 0; function update() { numframes++; if (new date - lasttime >= 1000) { lastframes = numframes; numframes = 0; lasttime = new date; } } 

here, lastframes give number of frames on approximately past second. when used in chrome, firefox, , safari, code doesn't run @ 1 millisecond. of course, each browser has arbitrary minimum time between setinterval calls, expected. however, page continues run, frame rate continue decrease, if tab still focused. way i've found fix make browser something. along these lines seems make browser run setinterval fast can:

function start() { window.setinterval(function() { update(); }, 1); } lasttime = new date; numframes = 0; lastframes = 0; function update() { numframes++; if (new date - lasttime >= 1000) { lastframes = numframes; numframes = 0; lasttime = new date; } //dointensiveloop, processing, etc. } 

thus, question this: browser looking justify running setinterval closer ask to?

edit: html5 spec says browsers should not allow setinterval run @ interval lower 4ms.

i think first, have ask ourselves expect interval functions:

  • they have maintain context: interval in not increment counter reliably quite disastrous

  • they should execute whatever in function, has priority on execution interval (same here, timer has go before increment again)

  • it should have separate execution stack rest of our js code (we don't want wait timers finish business until rest starts executing);

  • they should aware of context they're in, no matter how vast (we want able use jquery inside our timer functions, example).

so, matt greer said above, intervals design not exact, , that's because not expect them exact, reliably executing code @ given time.

if have @ chromium implementation, see implementation of settimeout , setinterval based on domtimer::install, gets passed execution context, action , if timer single shot

this gets passed runlooptimer, executes loop of system timers (as see here)

(by way, chromium installs minimum of 10ms interval, can see here)

every execution of action handled here, no assertion whatsoever on time passed since last execution being on or under timing limit.

in contrary, asserts timer nesting level does not deep slowing down timers using resources / running given interval this:

if (m_nestinglevel >= maxtimernestinglevel) augmentrepeatinterval(minimuminterval - repeatinterval()); } 

augmentrepeatinterval adds more milliseconds interval:

void augmentrepeatinterval(double delta) { augmentfireinterval(delta); m_repeatinterval += delta; } 

so, can conclude?

  • measuring time accuracy of intervals or timeouts a waste of time. thing should , can care don't set intervals low things want execute in function. browser best can execute intervals , timeouts in timely fashion, won't guarantee exact timing.

  • the interval execution depends on environment, browser, implementation, version, context, action , on , on. not meant exact, , if want program exact settimeout or setinterval, you're either crazy or go crazy later.

  • you said in code, when added heavy execution functions, timer got more accurate. can different reasons (maybe gets more memory, more exclusive cpu time, more workers , on). i'm interested in that, did not provide code did heavy execution yet. if want answers on that, please provide code, because it's difficult assume without it.

  • but whatever makes intervals run more timely, it's not reliable in way. kinds of various results if start measuring on different systems.


update

other that, code not lead may optimized (not executed, executed once, executed in better way) browser js engine. let me give example based on yours (all things executed in chromium):

function start() { window.setinterval(function() { update(); }, 1); } lasttime = new date; numframes = 0; lastframes = 0; function update() { console.log(new date() - lasttime); lasttime = new date(); (var i=0; < 1000000; i++) { var k = 'string' + 'string' + 'string' } } 

you find first execution after hit start take ages, whereas further executions don't (at least in webkit). that's because code in iteration not change anything, , browser recognizes after first execution , not execute anymore.

let's how changes if execution has maintain binding outer variable (kin case):

var k; function update() { console.log(new date() - lasttime); lasttime = new date(); (var i=0; < 1000000; i++) { k = 'string' + 'string' + 'string' } } 

ok, here have impact on execution time, still quite fast. browser knows loop same thing, executes once. if iteration create huge string, example?

var k; function update() { console.log(new date() - lasttime); lasttime = new date(); k = ''; (var i=0; < 1000000; i++) { k += i.tostring() } } 

this puts browser in world of hurt, because has return millions-of-characters string. can make more painful?

var k; function update() { console.log(new date() - lasttime); lasttime = new date(); k = ''; (var i=0; < 1000000; i++) { k = ['hey', 'hey', 'hey'].join('') } } 

this array concatenation cannot optimized , choke browser , painfully.

so, in case, heavy execution may have lead more memory reserved , instantly freed optimizer. may breath of fresh air , memory , idle cpu made function jump joy, said, there's nothing reliable there without having looked @ heavy execution code.


Comments

Popular posts from this blog

javascript - backbone.js Collection.add() doesn't `construct` (`initialize`) an object -

php - Get uncommon values from two or more arrays -

Adding duplicate array rows in Php -