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();