利用 Page Visibility API 最佳化網頁效能與使用者體驗

_zhiqiu發表於2024-09-29

在現代 Web 開發中,使用者可能會頻繁切換標籤頁,或讓網頁處於後臺執行。為了避免不必要的資源浪費並提升使用者體驗,合理利用 Page Visibility API 可以在頁面不可見時暫停或減少資源的消耗,並在頁面重新可見時恢復正常操作。

在這篇部落格中,我將展示如何透過 Page Visibility API 實現以下場景:

  1. 當使用者切換標籤頁時暫停影片或音訊播放。
  2. 當頁面不可見時停止資源密集型的動畫。
  3. 頁面不可見時停止 API 請求,並在頁面可見時重新開始。
  4. 當使用者返回頁面時恢復定時操作。

什麼是 Page Visibility API?

Page Visibility API 是一個瀏覽器提供的 API,它可以告訴我們頁面的可見性狀態。當頁面變為不可見時,我們可以暫停一些不必要的操作,比如動畫或媒體播放。這個 API 提供了兩個核心功能:

  • document.hidden:返回一個布林值,指示頁面當前是否隱藏。
  • document.visibilityState:返回頁面的可見性狀態,可以是 'visible'(頁面可見)、'hidden'(頁面隱藏)或 'prerender'(頁面正在預渲染)。
  • visibilitychange 事件:當頁面的可見性狀態(document.visibilityState)改變時觸發。

visibilityState 的作用

document.visibilityState 提供比 document.hidden 更直觀的資訊。它不僅告訴你頁面是否隱藏,還能進一步區分頁面是否正在預渲染。例如,你可以根據不同的狀態採取不同的最佳化措施。

瀏覽器相容性

雖然 Page Visibility API 很有用,但它的相容性在不同瀏覽器中略有差異。以下是各主流瀏覽器的支援情況:

Document.hiddendocument.visibilityState

瀏覽器 支援情況 版本
Chrome 支援 自 33 版本起
Firefox 支援 自 18 版本起
Safari 支援 自 7 版本起
Edge 支援 自 12 版本起
Opera 支援 自 20 版本起

visibilitychange 事件

瀏覽器 支援情況 版本
Chrome 支援 自 62 版本起
Firefox 支援 自 56 版本起
Safari 支援 自 14.1 版本起
Edge 支援 自 18 版本起
Opera 支援 自 49 版本起

使用者切換標籤頁時暫停影片播放

當使用者切換標籤頁時,繼續播放影片會浪費頻寬和資源。透過 Page Visibility API,可以在頁面不可見時暫停影片,等使用者返回後再自動恢復播放。

const videoElement = document.querySelector("video");

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        // 頁面隱藏時暫停影片
        videoElement.pause();
        console.log("頁面隱藏,影片暫停");
    } else if (document.visibilityState === 'visible') {
        // 頁面可見時恢復影片播放
        videoElement.play();
        console.log("頁面可見,影片繼續播放");
    }
});

頁面不可見時停止資源密集型動畫

動畫可能是效能瓶頸,尤其是在頁面不可見時執行動畫毫無意義。透過 Page Visibility API,我們可以在頁面不可見時暫停動畫,減少 CPU 和 GPU 的消耗。

let animationRunning = true;

function startAnimation() {
    if (!animationRunning) return;
    // 假設這裡有動畫邏輯
    console.log("動畫正在執行...");
    requestAnimationFrame(startAnimation);
}

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        // 頁面隱藏時停止動畫
        animationRunning = false;
        console.log("頁面隱藏,動畫停止");
    } else if (document.visibilityState === 'visible') {
        // 頁面可見時恢復動畫
        animationRunning = true;
        startAnimation();
        console.log("頁面可見,動畫恢復");
    }
});

startAnimation();

頁面不可見時停止 API 請求

某些情況下,持續的資料獲取可能會浪費頻寬。透過檢測頁面的可見性,可以在頁面不可見時停止資料請求,最佳化頻寬使用。

let requestInterval;

function startFetchingData() {
    requestInterval = setInterval(() => {
        // 模擬 API 請求
        console.log("正在獲取資料...");
    }, 5000);
}

function stopFetchingData() {
    clearInterval(requestInterval);
    console.log("停止獲取資料");
}

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        // 頁面隱藏時停止資料獲取
        stopFetchingData();
    } else if (document.visibilityState === 'visible') {
        // 頁面可見時恢復資料獲取
        startFetchingData();
    }
});

startFetchingData();

頁面可見時恢復定時操作

當頁面不可見時,某些定時任務可以暫停,直到使用者返回頁面時再恢復執行。這有助於提升資源利用效率。

let intervalId;

function startTimer() {
    intervalId = setInterval(() => {
        console.log("計時器正在執行...");
    }, 1000);
}

function stopTimer() {
    clearInterval(intervalId);
    console.log("計時器停止");
}

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        // 頁面隱藏時停止計時器
        stopTimer();
    } else if (document.visibilityState === 'visible') {
        // 頁面可見時恢復計時器
        startTimer();
    }
});

startTimer();

使用者返回頁面時恢復音訊播放

與影片類似,音訊在頁面不可見時繼續播放不僅對使用者無意義,還會浪費系統資源。透過 Page Visibility API 可以在使用者返回頁面時恢復音訊播放。

const audioElement = document.querySelector("audio");

document.addEventListener("visibilitychange", function() {
    if (document.visibilityState === 'hidden') {
        // 頁面隱藏時暫停音訊
        audioElement.pause();
        console.log("頁面隱藏,音訊暫停");
    } else if (document.visibilityState === 'visible') {
        // 頁面可見時恢復音訊播放
        audioElement.play();
        console.log("頁面可見,音訊繼續播放");
    }
});

結論

Page Visibility API 是一個簡單但非常有效的工具,能夠讓開發者根據頁面的可見性來動態最佳化資源的使用。結合 document.visibilityState,你可以進一步細化頁面狀態的控制,如在頁面預渲染時暫停某些操作。

這種最佳化不僅提升了使用者體驗,還能顯著減少系統資源的浪費。透過合理利用這個 API,我們可以暫停後臺的影片、音訊、動畫、資料請求等操作,並在使用者重新關注頁面時迅速恢復,達到效能和體驗的雙重提升。

在開發過程中,別忘了考慮瀏覽器的相容性問題,確保在所有平臺上提供一致的使用者體驗。希望這篇文章能夠幫助你更好地掌握 Page Visibility API 並將其應用到實際專案中。

參考內容

  • 頁面可見性 API - Web API | MDN (mozilla.org)
  • Document:visibilitychange 事件 - Web API | MDN (mozilla.org)
  • Document:hidden 屬性 - Web API | MDN (mozilla.org)
  • Document.visibilityState - Web API | MDN (mozilla.org)

相關文章