PWA Idle Detection 閒置偵測 實作狀態感知機制以優化背景資源消耗與安全性

me
林彥成
2021-09-24 | 3 min.
文章目錄
  1. 1. 什麼是 Idle Detection API?
  2. 2. 什麼是 Idle Detection API?PWA 閒置偵測解析
    1. 2.1. 閒置偵測功能可以解決什麼問題?
  3. 3. Idle Detection API 實作教學:如何偵測空閒狀態?
    1. 3.1. 核心實作流程與 IdleDetector 範例
  4. 4. FAQ:PWA 閒置偵測常見問題
    1. 4.1. Q1:我可以設定低於 60 秒的 threshold 嗎?
    2. 4.2. Q2:為什麼 IdleDetector.requestPermission() 會失敗?
    3. 4.3. Q3:visibilitychange 與 IdleDetector 有什麼本質區別?

什麼是 Idle Detection API?

Idle Detection API 是一種 Web API,允許 Progressive Web App (PWA) 偵測使用者是否處於閒置狀態(Idle),或是其裝置螢幕是否已鎖定。它不僅能監控滑鼠、鍵盤與觸控操作的停止,還能偵測作業系統級別的狀態變更。透過 IdleDetector 介面,開發者可以在使用者離開時自動將通訊狀態改為「離開」、在閒置時暫停耗能的動畫運算,或在公用展示機無人使用時自動重置頁面。這項技術強化了 Web 應用的智慧感與節能效率,是實現精準使用者狀態感知的關鍵工具。


什麼是 Idle Detection API?PWA 閒置偵測解析

Idle Detection API 的設計初衷,是當用戶與 App 的互動停止(閒置)超過設定的時間時,讓程式能自動觸發特定動作。雖然目前這個 API 還在提議與實驗階段,但小編覺得它的潛力非常巨大。

您可以參考 WICG 規範文件 來深入了解細節。

閒置偵測功能可以解決什麼問題?

在開發 Progressive Web App 時,掌握用戶的活躍狀態非常有幫助:

  • 社群應用:自動將聯絡人狀態切換為「離開」。
  • 公共展示機:若無人使用,自動重置並回到首頁。
  • 效能優化:將耗費資源的運算(如數據同步)推遲到用戶閒置時執行。

在有這個 API 前其實有個 visibilitychange 事件能夠達到一半的目的,瀏覽器會偵測是否還 Focus 在當前的 Tab。

1
2
3
4
5
6
7
document.addEventListener("visibilitychange", function () {
if (document.visibilityState === "visible") {
backgroundMusic.play();
} else {
backgroundMusic.pause();
}
});

Idle Detection API 實作教學:如何偵測空閒狀態?

在進行 Idle Detection API 實作 時,主要會從以下兩個維度進行偵測:

  • 用戶空閒狀態:停止操作(activeidle)。
  • 螢幕空閒狀態:螢幕鎖定(lockedunlocked)。
1
2
3
4
5
6
7
8
9
enum UserIdleState {
"active",
"idle"
};

enum ScreenIdleState {
"locked",
"unlocked"
};

核心實作流程與 IdleDetector 範例

小編整理了官方推薦的標準實作流程如下:

  1. 看瀏覽器是否存在 API。
  2. 取得相關權限。
  3. New 一個 IdleDetector,最小的 threshold 目前是 60 秒。
  4. 可以透過 AbortController 去終止。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const main = async () => {
// 檢查瀏覽器是否支援 API
if (!("IdleDetector" in window)) {
return console.log("IdleDetector is not available.");
}
// 必須先取得使用者授權
if ((await IdleDetector.requestPermission()) !== "granted") {
return console.log("Idle detection permission not granted.");
}

try {
const controller = new AbortController();
const signal = controller.signal;

const idleDetector = new IdleDetector();
idleDetector.addEventListener("change", () => {
// 當狀態改變時觸發邏輯
console.log(
`Idle change: User is ${idleDetector.userState}, Screen is ${idleDetector.screenState}.`
);
});

await idleDetector.start({
threshold: 60000, // 偵測門檻,單位為毫秒(最小 60 秒)
signal,
});
console.log("IdleDetector is active.");

// 設定 2 分鐘後自動停止偵測
window.setTimeout(() => {
controller.abort();
console.log("IdleDetector is stopped.");
}, 120000);
} catch (err) {
// 處理權限被拒絕、在非頂層 Frame 執行等錯誤
console.error(err.name, err.message);
}
};

main();

這也是 PWA 教學 中非常強調的「漸進式增強」實際案例:讓 App 能夠在支援的瀏覽器上提供更智能的功能,而在不支援的環境下依然能維持基本運作。

這個頁面在勾選觸發後,只要在 60 秒不活動後就會清除繪畫的內容。這個應用案例可以想像這成被部署在公眾場合供參觀的使用者塗鴉。

Demo 連結: https://idle-detection.glitch.me/


FAQ:PWA 閒置偵測常見問題

Q1:我可以設定低於 60 秒的 threshold 嗎?

A:目前 API 的實作中,最小的偵測門檻 (Threshold) 被限制在 60,000 毫秒(1 分鐘)。這是為了防止惡意網站過度頻繁地監控使用者行為,保護使用者隱私與裝置電力。

Q2:為什麼 IdleDetector.requestPermission() 會失敗?

A:除了使用者拒絕外,常見的原因還有:1. 網站未在 HTTPS 環境下執行;2. 呼叫權限請求時並非由使用者行為(如點擊)觸發;3. 該 API 目前仍屬於實驗性階段,某些瀏覽器(如 Safari 或 Firefox)預設可能尚未開啟。

Q3:visibilitychangeIdleDetector 有什麼本質區別?

A:visibilitychange 僅偵測瀏覽器分頁是否被切換或最小化;而 IdleDetector 偵測的是全域的閒置。即使 PWA 頁面正開著且在最上層,如果使用者離開座位一分鐘不碰滑鼠,IdleDetector 也會觸發,但 visibilitychange 則不會。


掌握了 Idle Detection API,您就能為您的 PWA 增添一份敏銳的「自覺」。無論是自動節能還是智慧狀態切換,都能讓產品的細節體驗更上一層樓!


喜歡這篇文章,請幫忙拍拍手喔 🤣