1

I would like to know how accurate is the setTimeout method in javascript. Does it have any threshold above that it will exactly postpone so many milli sec or, does it exactly perform the function specified irrespective of the milli sec value.

1
  • It is is inaccurate, varies from 0 to 10ms every 100ms using Chrome Windows. Less with Firefox but not much. Do not rely on it for accuracy. Commented Jun 25, 2016 at 15:49

3 Answers 3

8

JavaScript doesn't have a setTimeout method. Browsers and some other environments in which JavaScript runs do.

The HTML5 specification sets out rules on setTimeout and its cousins (generally, "timers") for browsers in §6.4- Timers.

In general, a timer will fire reasonably accurately provided the thread that its callback needs to run on isn't busy doing something else. But that's a big proviso. The callback can't be run if the thread is busy and will wait in a job queue until the thread gets to it, so you can't be sure that it'll fire right when expected, particularly not if you're using the default thread JavaScript runs on in browsers, which handles UI. It won't run earlier,1 but it may well run later than you expect.

Browsers also change how timers operate in various ways when the window they're running in is hidden (for instance, it's an inactive tab).

Here's a snippet to measure how well your browser does on the main UI thread:

var results = [];
var disp = {
    min: document.getElementById("min").firstChild,
    max: document.getElementById("max").firstChild,
    avg: document.getElementById("avg").firstChild,
    count: document.getElementById("count").firstChild
};

var now = (function() {
    if (typeof performance !== "undefined" && performance.now) {
        return function() {
            return performance.now();
        };
    }
    return function() {
        return Date.now();
    };
})();

function test() {
    var delay = Math.floor(Math.random() * 50) + 10;
    var start = now();
    setTimeout(function() {
        var elapsed = now() - start;
        var result = {
            delay: delay,
            elapsed: elapsed,
            diff: elapsed - delay
        };
        logResult(result);
        results.push(result);
        if (results.length <= 500) {
            test();
        }
    }, delay)
}

function log(msg, atTop) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    if (atTop) {
        p.style.borderBottom = "1px solid black";
        document.body.insertBefore(p, document.body.firstChild);
    } else {
        document.body.appendChild(p);
    }
}

function logResult(r) {
    log("expected " + r.delay + ", got " + r.elapsed + ", diff: " + r.diff);
    summary();
}

function summary() {
    var sum = 0,
        min = Infinity,
        max = -Infinity;
    results.forEach(function(r) {
        var d = r.diff;
        sum += d;
        min = Math.min(min, d);
        max = Math.max(max, d);
    });
    disp.min.nodeValue = min.toFixed(4);
    disp.max.nodeValue = max.toFixed(4);
    disp.avg.nodeValue = (sum / results.length).toFixed(4);
    disp.count.nodeValue = results.length;
}

setTimeout(test, 500);
.summary {
  border-bottom: 1px solid #ddd;
  padding-bottom: 4px;
}
<div class="summary">
Variance in milliseconds:
<br>
Min: <span id="min">-</span> |
Max: <span id="max">-</span> |
Avg: <span id="avg">-</span> |
Count: <span id="count">-</span>
</div>


1 "...it won't run earlier..." - Apparently (from the snippet above) on Firefox it can run a fraction of a millisecond early. I put that down to the fact that timers work in whole milliseconds. Apparently if you schedule a timer at 12:30:04.0415 (half a millisecond after 12:30:04 and 41ms) for 20ms, it'll fire it at 12:30:04.061 (12:30:04 plus 61ms exactly) rather than waiting until 12:30:04.0615 (12:30:04 plus 61.5ms). E.g., apparently it takes 12:30:04.0415, disregards the fractional milliseconds to get 12:30:04.041, adds 20 to get 12:30:04.061, and fires as soon as it can after that.

Sign up to request clarification or add additional context in comments.

Comments

1

You should assume that any timeout function will wait "at least" the specified period of time. But it might be longer. "How much longer" is unpredictable.

Comments

1

Depends on the implementation and environment.

There are any number of factors, e.g., on the browser side, inactive tabs and user settings, on the server side and OS interaction.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.