3

What's the best way to create a timer in JS?

I've been using this so far:

var sec = 0;
setInterval(function (){sec +=1}, 1000);

I've noticed that, when I need miliseconds, it slows down by a lot. On browser tab changes, it completely stops.

var milisec = 0;
setInterval(function (){milisec +=1}, 1);

I'm looking for a better way to handle this, which will also continue to work when the browser window is changed.

Mia
  • 6,220
  • 12
  • 47
  • 81

2 Answers2

4

With milliseconds, the resolution of the timer isn't large enough. In most cases the callback won't be called more often than roughly 50 to 250 times per second, even when you set the interval to 1ms. See Timer resolution in browsers (as referred to by Sani Huttunen) for an explanation.

With 1000ms it will work better. But still the timer won't be fired when the tab is inactive, and may be delayed when the cpu is busy or another script is running on your page.

One solution is to not increment a counter, but to test how much time has actually passed since the previous call of the timer. That way, the timing remains accurate, even when the intervals have been delayed or paused inbetween.

This snippet will remember the start date, and on each timer interval, update seconds and milliseconds to the difference between the current time and the start time.

var start = new Date();
var milliseconds = 0;
var seconds = 0;
setInterval(function()
{
    var now = new Date();
    milliseconds = now.getTime() - start.getTime();
    seconds = round(milliseconds / 1000);
}, 1000);

I've set the interval to 1000 again. You might set it shorter, but it will cost more performance.

Related question: How can I make setInterval also work when a tab is inactive in Chrome?

Community
  • 1
  • 1
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • Your answer is not that different from having a set interval honestly - but it inspired me to find an alternative solution for updating things. I'm sharing my solution as an answer for future reference. – Mia Oct 08 '14 at 13:44
  • 2
    My answer is also having a set interval. That part it the same. The difference is in how you calculate which (milli)second it is. – GolezTrol Oct 08 '14 at 13:46
  • A good example why a good problem description is relevant to a question. Apparently you didn't need a timer at all, you just needed to know how much time has passed since the page was loaded. Anyway, the answer helped you, and that's important. – GolezTrol Oct 08 '14 at 13:57
0

Based on @goleztrol's solution, I've created an alternate solution specifically for my situation (it might not work for everyone).

I just ask the exact time when it's needed with this function, to know the exact miliseconds passed:

var start = new Date();
var msPassed = function() {
    var now = new Date();
    var ms = now.getTime() - start.getTime();
    return ms
}

msPassed(); //returns time passed in ms

I needed to position objects (on creation) depending on how much time passed until their creation, so for my case this is a perfect solution. However, my initial question asks for the perfect timer, and this is not it. Anyway, here it is for future reference.

Mia
  • 6,220
  • 12
  • 47
  • 81