Open Bug 1838761 Opened 2 years ago Updated 1 year ago

setTimeout (and, by extension setInterval) consistently fires too slowly

Categories

(Core :: DOM: Core & HTML, defect)

Firefox 114
Desktop
Windows 10
defect

Tracking

()

UNCONFIRMED

People

(Reporter: pascal, Unassigned)

References

(Depends on 1 open bug)

Details

Steps to reproduce:

This is an issue still present in the current Firefox Nightly 116.0a1. The oldest version I've tried, which exhibits the same behavior, is the currently live 114.0.1, hence why I'm filing this bug under that version.

The setTimeout() (and, by extension, the setInterval()) function consistently fires too slowly, with a deviation of up to over 50% (for instance, a setTimeout((), 20) firing after 35ms instead). The delay seems unpredictable when the timeout is fired sporadically, but stays fairly consistent (within 1-2ms, barring the occasional larger deviation that's to be expected) when fired regularly, or within a setInterval(), though the general length of the delay can vary greatly depending on when the interval is first started.

I've tested this on daily driver installs across multiple machines, as well as fresh installs of both the live version 114.0.1 and Nightly 116.0ai, and the issue consistently appears.

It can be reliably reproduced by running the following code in the developer console:

function testTimeout() {
    let lastTimestamp = performance.now();

    window.setTimeout(() => {
        let duration = performance.now() - lastTimestamp;
        console.log(duration)
    }, 50);
}

testTimeout();

Or, to test an interval:

function testInterval() {
    let lastTimestamp = performance.now();

    window.setInterval(() => {
        let duration = performance.now() - lastTimestamp;
        lastTimestamp = performance.now();
        console.log(duration)
    }, 50);
}

testInterval();

I'm aware that minor deviations are to be expected, and timeouts and intervals aren't supposed to be an exact science, but this seems far too consistently slow, and far too slow in general, to me.

Actual results:

A timeout (or interval) set to fire after (or every) 50ms fires consistently slowly, sometimes with a minor deviation of around ~5ms, sometimes with massive deviations of +15ms.

Expected results:

A timeout A timeout (or interval) set to fire after (or every) 50ms should fire roughly after 50ms, with a few minor deviations here and there.

The Bugbug bot thinks this bug should belong to the 'WebExtensions::Untriaged' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Product: Firefox → WebExtensions
Product: WebExtensions → Firefox
Component: Untriaged → DOM: Core & HTML
Product: Firefox → Core
OS: Unspecified → Windows 10
Hardware: Unspecified → Desktop
Severity: -- → S3
Flags: needinfo?(jlink)

In general, per specification, user agent can add any kind of extra delay to setTimeouts/Intervals. And browsers are experimenting with various ways to reduce power usage, so multiple timers may get run at the same time so that number of wake ups could be decreased.

And on Windows Gecko defaults to low precision timers, at least currently.

Depends on: 1826224
Duplicate of this bug: 1857495
Depends on: 1881627

The current plan is to adjust the timer resolution dynamically based on the requirements of the upcoming timers - high resolution when precisely-firing timers are coming up soon, low resolution when not. I have done some work to start on this but haven't quite found the time to finish it up yet.

Flags: needinfo?(jlink)
You need to log in before you can comment on or make changes to this bug.