5

I build a web app and I use setInterval with 500ms timer for some clock.

When the window is active the clock runs perfect, I use that:

var tempTimer = 0;
setInterval(function () {
    goTimer()
}, 500);

function goTimer() {
    tempTimer++;
    $("#timer").val(tempTimer);
}

But the problem is when the window/tab becomes inactive - the interval is changed to 1000ms!

When i focus the window/tab again, it changes back to 500ms.

check this out: http://jsfiddle.net/4Jw37/

Thanks a bunch.

Avni Yayin
  • 469
  • 1
  • 8
  • 18
  • 1
    Yes, that's a true observation (well …ish, the JS thread just gets less CPU time so it checks to see if there is an interval event waiting to run less frequently). What's your question? – Quentin May 06 '14 at 23:18
  • You should just use performance.now() or Date.now() and compare the time stamps to get your elapsed time. This way your interval can jump all over the place but your data will still be correct. – ericjbasti May 06 '14 at 23:22
  • 1
    http://stackoverflow.com/questions/5927284/how-can-i-make-setinterval-also-work-when-a-tab-is-inactive-in-chrome – Black Sheep May 06 '14 at 23:23
  • Similar question I asked a while back: http://stackoverflow.com/questions/8173580/setinterval-timing-slowly-drifts-away-from-staying-accurate – Alex Wayne May 06 '14 at 23:24
  • 2
    Note you can use `setInterval(goTimer, 500)`, without a wrapping function. – Oriol May 06 '14 at 23:28
  • my question is how I keep that clock working as i need that to work? My clock speed is x2 (1 real second = 2 of my clock seconds) – Avni Yayin May 06 '14 at 23:43

3 Answers3

4

Yes, this behavior is intentional.

See the MDN article:

In (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) and Chrome 11, timeouts are clamped to firing no more often than once per second (1000ms) in inactive tabs; see bug 633421 for more information about this in Mozilla or crbug.com/66078 for details about this in Chrome.

And the spec says:

Note: This API does not guarantee that timers will run exactly on schedule. Delays due to CPU load, other tasks, etc, are to be expected.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • That sucks. My clock speed is x2 (1 real second = 2 of my clock seconds), anyone got any idea how to work this out? – Avni Yayin May 06 '14 at 23:25
  • Web Workers run in a separate thread in realtime. Use those, if you have time critical stuff. https://github.com/cwilso/metronome/ – Mantriur May 24 '15 at 22:52
3

You seem to want a timer that increments every half second. You can do that much more accurately by keeping track of the total time since you started and doing some math.

var tempTimer = 0;
var startedTimer = Date.now();
setInterval(goTimer, 250); // a little more often in case of drift

function goTimer() {
    tempTimer = Math.floor((Date.now() - startedTimer) / 500);
    $("#timer").val(tempTimer);
}

See this work here: http://jsfiddle.net/4Jw37/2/

So this does update every half second, but it doesn't need to. If it skips a few beats it will fix itself the next time it fires because it's recalculating each time based on the time since it started tracking. The number of times the function runs is now has no effect on the value of the counter.

So put in another way, do not ask how many times you incremented the count. Instead ask how many half second segments have passed since you started.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
0

For time interval, Browsers may not behave similar for both active and inactive window.

What you can do, When you are setting the time interval you can save the timestamp(initial time). On window.onfocus, take on there timestamp (now) find the difference between initial time and now and use that update the tempTimer.

Nafis Ahmad
  • 2,689
  • 2
  • 26
  • 13