解決 PWA 後台休眠:Web Worker 打造的心跳起搏器
在開發行動端 Web 應用程式時,開發者面臨的最大挑戰之一就是後台限制。現代手機操作系統 (iOS/Android) 為了極致省電,會對非活躍分頁進行無情的「降頻」甚至「凍結」。這對需要持續監控市場動態的 Hyperliquid Monitor 來說是個致命傷。
💀 問題:手機瀏覽器的「假死」 (The Problem)
當你鎖定螢幕,或切換到其他 App 時,Chrome 或 Safari 會認為當前網頁不再需要高性能運作。瀏覽器會將主線程的 setInterval 頻率降到極低(例如 1 分鐘才執行一次),甚至完全暫停執行。如果我們的監控系統需要每 10 秒檢查一次數據並發出警報,這種降頻會讓工具變得毫無意義。
✅ 解決方案:Web Worker 作為「計時起搏器」
為了繞過這個限制,我們引入了獨立的 timer.worker.js。
技術原理
Web Worker 運行在與主 UI 線程完全獨立的線程中。雖然瀏覽器對後台 Worker 仍有限制,但其「被寬容度」通常比主線程高得多。
- 分離職責: 主 UI 線程負責渲染畫面與網絡請求,而 Worker 僅負責一件簡單的事:計時。
- 訊息通訊:
- 主線程啟動 Worker 並告知間隔時間(例如 10,000ms)。
- Worker 內部啟動
setInterval,並在每次到點時發送一個簡單的"tick"訊息回主線程。
- 喚醒主流程: 主線程監聽到 Worker 的訊息後,被強行「喚醒」來執行重型的數據輪詢邏輯。
代碼實踐
Worker 線程 (timer.worker.js):
// Worker 保持「愚蠢」,只負責計時
self.onmessage = function(e) {
if (e.data.action === 'start') {
setInterval(() => self.postMessage('tick'), e.data.interval);
}
};
主線程 (app.js):
if (window.Worker) {
const pollWorker = new Worker('timer.worker.js');
pollWorker.onmessage = (e) => {
if (e.data === 'tick') pollLatest(); // 被喚醒,執行數據抓取
};
pollWorker.postMessage({ action: 'start', interval: 10000 });
}
⚖️ 權衡與代價
雖然 Web Worker 方案大幅提升了鎖屏後的警報可靠性(實測在 Android 下鎖屏 30 分鐘仍能穩定運行),但它並非萬能藥:
- 非原生後台: 這仍受限於瀏覽器進程的生命週期。如果系統記憶體吃緊,整個瀏覽器仍可能被殺死。
- 記憶體佔用: 多開一個線程會增加些微的資源開銷。
結論
在純 Web 技術的限制下,利用 Web Worker 作為「心跳起搏器」是實現高頻後台監控的最優解。它平衡了電力消耗與任務實時性,為 PWA 應用程式開啟了更多可能性。