非活跃标签页下JavaScript无法运行的问题咨询
Hey there! Let's break down what's going on with your code, and why your other game doesn't have this issue.
The Root Cause: Browser Timer Throttling
Here's the thing: modern browsers throttle timers like setInterval and setTimeout in inactive tabs to save CPU and battery life. For intervals shorter than 1000ms, browsers will force them to run no more than once per second when the tab isn't active. That's why your 10ms interval seems to "stop"—it's actually running once every second instead of 100 times per second, making the count crawl.
Your original code runs entirely on the main thread, so it's subject to this throttling:
num = 0; window.setInterval(function() { num = num + 1; document.getElementById('num').innerHTML = num; }, 10);
Why Your Other Game Works
Your game likely avoids this throttling for one of these reasons:
- It uses Web Workers: Game logic runs in a separate background thread (a Web Worker) that's not affected by tab activity throttling. Timers in Workers run at their intended interval regardless of whether the tab is active.
- It uses event-driven logic: Instead of relying on timers, it might react to user input, network events (like WebSockets), or high-priority APIs (like Web Audio's clock, which isn't throttled).
- Its timers are already slow: If the game uses intervals longer than 1 second, browsers don't apply this throttling rule.
Fixes to Keep Your Code Running in Background Tabs
1. Use a Web Worker (Best for Precise Timing)
Move your interval logic to a Web Worker, which runs independently of the main thread and avoids throttling.
First, create a file named worker.js:
let num = 0; setInterval(() => { num += 1; self.postMessage(num); // Send the updated count to the main thread }, 10);
Then update your HTML to use the Worker:
<html> <head> <title>Space...</title> </head> <body> <span id="num">0</span> <script> // Create a new Worker instance const counterWorker = new Worker('worker.js'); // Listen for messages from the Worker and update the DOM counterWorker.onmessage = (event) => { document.getElementById('num').textContent = event.data; }; </script> </body> </html>
2. Adjust for Throttling (If Precision Isn't Critical)
If you don't need millisecond-level precision, you can detect tab activity with the document.hidden API and adjust your timer behavior:
let num = 0; let intervalId; function startInterval() { intervalId = setInterval(() => { num += 1; document.getElementById('num').textContent = num; }, document.hidden ? 1000 : 10); // Slow down when tab is inactive } // Listen for tab visibility changes document.addEventListener('visibilitychange', () => { clearInterval(intervalId); startInterval(); }); startInterval();
This doesn't fix the throttling, but it makes your code behave consistently instead of appearing to stop.
内容的提问来源于stack exchange,提问作者William Jones

