Ways to keep setTimeout/setInterval from being paused in Edge browsers

When the edge browser goes into the background, the setTimeout timer in its web page may be suspended due to performance optimisation policies until the page regains focus again.

There are two ways to avoid this.

Method 1: Turn off edge efficiency mode

Press Alt + F in edge browser and select Settings -> System and Performance -> Optimize Performance. You can also enter the address edge://settings/system in the address bar and enter to go directly to the settings page.

Then turn off the Efficiency mode and Save resources with sleeping tabs switches in the page. However, for laptops, the efficiency mode helps to save power consumption, so you can decide whether you need to turn it off or not.

Method 2: Start and loop the audio file

Since method 1 requires user action, it is uncontrollable. For developers, it is possible to start a loop to play an audio file at the same time as the timer starts. This will not freeze the audio/video playback page on the PC version of the edge browser (not applicable to the mobile version).

Example:

function audioLoop() {
    const c3 = document.createElement("audio");
    c3.src = "data:audio/mp3;base64,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";
    c3.volume = 0.002;
    // Some browsers are very strict. You need to set the volume to a very low level, or change the audio file to one without sound.
    c3.loop = true;
    c3.play();
}
 
audioLoop();
setInterval(() => console.log(new Date()), 1000);

Note that:

  • Audio files that are looped need a small volume value, otherwise they will not be recognised by the browser.
  • The start of audio playback is dependent on user actions, and can be started when the user triggers a certain click behaviour.

Method 3: Create a looped invisible video playback

function isMobile() {
    return navigator.userAgentData?.mobile || /Mobi|Android|iPhone/i.test(navigator.userAgent);
}
function videoLoop() {
    const chromeVersion = /Chrome\/([0-9.]+)/.exec(navigator.userAgent)?.[1]?.split('.')[0];
 
    if (chromeVersion && parseInt(chromeVersion, 10) >= 88 && !isMobile()) {
        const videoDom = document.createElement('video');
        const hiddenCanvas = document.createElement('canvas');
 
        videoDom.setAttribute('style', 'display:none');
        videoDom.setAttribute('muted', '');
        videoDom.muted = true;
        videoDom.setAttribute('autoplay', '');
        videoDom.autoplay = true;
        videoDom.setAttribute('playsinline', '');
        hiddenCanvas.setAttribute('style', 'display:none');
        hiddenCanvas.setAttribute('width', '1');
        hiddenCanvas.setAttribute('height', '1');
        hiddenCanvas.getContext('2d')?.fillRect(0, 0, 1, 1);
        videoDom.srcObject = hiddenCanvas?.captureStream();
    }
}
videoLoop();
setInterval(() => console.log(new Date()), 1000);

Method 3: Run in Web Worker

Browsers will pause tabs in the background for performance optimisation reasons, but processes in the Web Worker will not be affected. We can put the timer logic into the Web Worker.

Example:

function init() {
    const blob = new Blob([`(function(e){setInterval(function(){this.postMessage(null)},1000)})()`]);
    const url  = window.URL.createObjectURL(blob);
    const work = new Worker(url);
    work.onmessage = () => {
        console.log(new Date());
    }
}
 
init();