養貓的人應該都有經驗,有時候當你看著貓的時候,他會瞬間定格、一動也不動地跟你對視;但只要你一轉過頭或走開,牠就會偷偷移動,等你轉回頭時又瞬間定格。好像突然開啟了一場123木頭人的遊戲。
在上一篇介紹 背景節流(Background Throttle) 時提到,瀏覽器為了節省能源,會在使用者切換分頁時自動幫網頁「降速」。
但身為前端開發者,該怎麼「主動知道」使用者到底有沒有在看我們的網頁呢?這時候就需要靠 Page Visibility API(頁面可見性 API)。
Page Visibility API(頁面可見性 API) 是瀏覽器提供的一個網頁 API,用來讓 JavaScript 開發者知道目前這個網頁分頁(Tab)是對使用者「可見」還是「隱藏」的。
在過去,瀏覽器無法精確判斷使用者是否正在觀看你的網頁。當使用者:
切換到別的分頁
將瀏覽器最小化
螢幕自動鎖定 / 關閉
網頁上的 JavaScript(如 setInterval 計時器、動畫、輪播圖、背景資料)依然會默默地在背景全力運作。這會帶來三大問題:
浪費使用者裝置的 CPU 與電力。
消耗不必要的網路流量(例如背景持續拉取 API 資料)。
導致資料計算不準確(例如音訊/影片在背景播完、遊戲在背景繼續運行)。
Page Visibility API 就是為了解決這個問題——讓網頁能夠根據使用者的視線離開或返回,自動暫停或恢復資源消耗。
這個 API 的用法非常簡單,主要由 document 的一個屬性與一個事件組成:
| 語法 | 類型 | 說明 |
|---|---|---|
| document.hidden | 屬性 (Boolean) | 當分頁被隱藏(切換分頁或最小化)時回傳 true,可見時回傳 false。 |
| document.visibilityState | 屬性 (String) | 回傳當前狀態,常見值為 'visible'(可見)或 'hidden'(隱藏)。 |
| visibilitychange | 事件 (Event) | 當頁面從前景切到背景,或從背景切回前景時觸發。 |
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
console.log("使用者離開了當前分頁(頁面隱藏)");
} else {
console.log("使用者回來了(頁面可見)");
}
});
const myVideo = document.querySelector("#my-video");
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
// 1. 使用者切換分頁時,自動暫停影片
myVideo.pause();
// 2. 暫停背景輪詢 API
stopDataPolling();
} else if (document.visibilityState === "visible") {
// 3. 切回分頁時,自動恢復播放
myVideo.play();
// 4. 重新開始輪詢 API
startDataPolling();
}
});
多媒體控制:當使用者切換分頁時,自動暫停 YouTube / 網頁影片播放或背景音樂,切回來時再恢復。
網頁即時通訊 / 輪詢 (Polling):當頁面在背景時,降低向伺服器請求資料(如新訊息通知)的頻率,節省流量。
網頁遊戲 (Web Games):分頁隱藏時自動暫停遊戲邏輯與渲染(requestAnimationFrame),避免背景過熱吃效能。
數據統計與埋點:精確統計使用者「真正停留在頁面上閱讀」的實際時間,排除分頁開著但沒在看的空白時間。
時間校正(搭配 Date.now()):切回前景時重新讀取當前時間戳記,校正因背景降頻(Background Throttling)而走慢的倒數計時器。
Page Visibility API 讓我們能好地配合瀏覽器的節能機制:
1. 掌握可見狀態: 善用 document.hidden 與 visibilitychange 事件。
2. 注重資源節約: 切到背景時主動暫停動畫、計時器與影片播放。
3. 優化使用者體驗: 切回前景時第一時間刷新與校正畫面數據。