Modern browsers are aggressive about saving power. When you switch away from a browser tab, Chrome and Edge begin throttling it โ slowing down JavaScript timers, pausing animations, and limiting background processing. For a keep-awake tool that relies on JavaScript running reliably in the background, this is a significant challenge. Here's how KeepAwake's Web Worker technique solves it.
The Browser Throttling Problem
When a browser tab becomes inactive โ you switch to another tab, minimize the window, or leave it in the background โ the browser applies a series of optimizations to reduce CPU and battery usage. For setTimeout and setInterval calls in inactive tabs, Chrome limits firing frequency to a minimum of 1 second for tabs that have been background for less than 5 minutes, and then progressively throttles more aggressively โ up to 1-minute minimum intervals for tabs that have been backgrounded for extended periods.
For a keep-awake tool that needs to maintain a steady heartbeat signal โ periodically reinforcing the wake lock request, refreshing the Picture-in-Picture session, or signaling activity through an AudioContext โ this throttling creates gaps. A timer that's supposed to fire every 30 seconds might only fire every 60 seconds, or less, after extended backgrounding.
In practice: a keep-awake tool that uses only page-level JavaScript timers can become unreliable if the browser tab is backgrounded for a long time. The tool appears to be running, but its internal heartbeat has been choked, and the underlying keep-awake signals start to lapse.
What Web Workers Are
A Web Worker is a JavaScript runtime that operates in a separate thread from the main browser page. It was designed for computationally intensive work that would otherwise block the user interface โ things like image processing, data parsing, or complex calculations. But Web Workers have a property that's directly relevant to keep-awake tools: they are explicitly exempt from background tab throttling.
According to the HTML specification, timers inside Web Workers are not subject to the same throttling rules as timers in page scripts. A setInterval running inside a Web Worker continues to fire at its specified interval regardless of how long the tab has been backgrounded, regardless of whether the tab is minimized, and regardless of the browser's aggressive power-saving optimizations.
This is by design โ Web Workers are intended for background processing that needs to run reliably. The spec authors explicitly carved them out of throttling rules for this reason.
How KeepAwake Uses This
KeepAwake runs a Web Worker that acts as a reliable heartbeat timer. Even when the KeepAwake browser tab is backgrounded and the page's own JavaScript is being throttled, the Web Worker continues firing at regular intervals. These heartbeat signals are used to:
- Periodically re-request the Screen Wake Lock (wake lock requests can lapse if not maintained)
- Check whether the Picture-in-Picture session is still active and reinitiate it if it has been closed
- Keep the AudioContext active, preventing the browser from suspending it during extended inactivity
- Post a message back to the main page thread to trigger any additional refresh logic
The result is that KeepAwake's keep-awake signals remain consistent and reliable even after hours of the tab sitting in the background โ no drift, no degradation, no "it stopped working at some point in the afternoon."
Why This Matters in Practice
Consider a typical remote work scenario: you open KeepAwake at 9am, click Start, then minimize the browser. You're now working in other applications all day โ Word, Outlook, Teams Desktop. The KeepAwake tab is sitting backgrounded in a Chrome window you never switch to.
Without Web Worker heartbeat: By mid-afternoon, Chrome's background throttling has progressively choked the page's JavaScript. The wake lock request has lapsed, the PiP session has timed out, and your Teams status has quietly flipped to Away โ without any indication that the tool has stopped working.
With Web Worker heartbeat: The Worker's timer fires unthrottled throughout the day. Every 30 seconds it reinitializes any lapsed signals. The wake lock stays active, the PiP session stays running, and your Teams status remains green continuously from 9am to end of day.
The Five-Technique Defense-in-Depth Model
KeepAwake's five simultaneous techniques โ Wake Lock, Picture-in-Picture, Web Worker heartbeat, AudioContext, and Canvas animation โ aren't redundant by accident. They represent a defense-in-depth approach where each technique covers a specific failure mode that the others might not catch:
- Wake Lock is the primary OS-level signal, but can lapse without maintenance
- Picture-in-Picture provides OS media session signaling, but requires an active video stream
- Web Worker provides the reliable heartbeat that keeps the others alive under throttling
- AudioContext provides an audio session signal for environments where Wake Lock has limited support
- Canvas animation provides a baseline browser activity signal as a last resort
The combination means that even in adversarial environments โ aggressive corporate power management, older browsers, long-backgrounded tabs, low-power mode โ at least two or three techniques remain active and effective. The practical result is the same regardless of your specific environment: your status stays green all day.
A Note on Service Workers
A Service Worker is a related but different concept โ it's a worker that persists even after the browser tab is closed, used for push notifications and offline caching. KeepAwake uses a regular Web Worker rather than a Service Worker because the goal is to maintain signals only while the tab is actively open, not to persist background processes after the user has closed it. This is both the technically correct approach and the more privacy-respecting one.