Use-Cases of this tutorial
- Know how browser modifies setTimeout() / setInterval() behavior that execute on background tabs.
Time delay for setTimeout() / setInterval() methods executing on inactive browser tabs are set to one second regardless of their value defined in code.
Timers methods setTimeout() / setInterval() running on background tabs can be resource exhausting. An application running callbacks at very short intervals in a background tab may drain a lot of memory to the point that the working of the currently active tab may be impacted. In the worst case, the browser may crash, or battery of the device would be rapidly used up.
In such cases, it makes sense to place some restrictions on the timers running in background tabs.
Browsers do exactly this. For inactive tabs, they automatically throttle timers to run every 1 second, regardless of the original delay specified in the code. For example, if the code originally used setInterval() to run some code every 50 ms, once the application is moved to a background tab, the interval automatically becomes 1000 ms (1 second).
However once the tab is re-activated, the original interval or delay returns to the original value.
Update, Jan 2021 : From Chrome 88+, timers can be throttled to 1 minute in certain conditions.
Making Sure Timer Throttling Does Not Result in Buggy Behavior
It is important to consider the scenario when the application's timers may get throttled when user moves to a different tab or minimizes the browser. For example, if the application runs an animation using setInterval(), the user may see a distorted form of the animation when he returns back to the original tab. This distortion may happen because the code that was supposed to execute every few milliseconds, ran every 1 second while the tab was inactive.
The Page Visibility API can be used to find if the user moved away from the tab, or came back to the tab again. Knowing this, timers can be temporarily paused when the tab is inactive.
document.addEventListener('visibilitychange', function() {
if(document.hidden) {
// tab is now inactive
// temporarily clear timer using clearInterval() / clearTimeout()
}
else {
// tab is active again
// restart timers
}
});