Chrome' 記憶體和節能模式的開發人員須知

Chrome 108 推出兩種新模式:記憶體節省模式和節能模式,讓使用者進一步控管 Chrome 如何利用系統資源。

雖然這些新模式主要面向使用者,但確實有一些影響值得網頁開發人員留意,因為這些模式可能會影響網站的使用者體驗。

這篇文章將說明這些新模式的潛在影響,以及網路開發人員可採取哪些措施,確保提供最佳體驗。

記憶體節省模式

啟用記憶體節省模式後,Chrome 會主動捨棄背景中閒置一段時間的分頁。這樣就能釋出記憶體,供使用中的分頁和其他可能正在執行的應用程式使用。使用者可以指示 Chrome 不要捨棄特定網站的分頁;不過,這是使用者偏好設定,開發人員無法控制。

當分頁遭到捨棄時,其標題和 favicon 仍會顯示在分頁列中,但頁面本身會消失,就像分頁已正常關閉一樣。如果使用者再次開啟該分頁,系統會自動重新載入網頁。

如果是純內容網頁,捨棄和重新載入分頁可能不會影響使用者體驗,但如果是含有複雜使用者流程的互動式網站,如果網站無法將網頁還原至使用者離開時的狀態,在流程中途重新載入網頁可能會讓使用者感到非常不便。

為節省記憶體,Chrome 多年以來一直會捨棄分頁,但這項操作只會在系統記憶體不足時執行。由於這類情況相對罕見,網頁開發人員可能不會察覺到這項問題。

從 Chrome 108 版開始,分頁捨棄的情況將更加普遍,因此網站必須能妥善處理這些情況。

處理分頁捨棄的最佳做法

分頁捨棄對網頁開發人員來說並非新挑戰。使用者在完成工作前,總是可以重新載入網頁 (無論是故意或意外)。因此,網站儲存使用者狀態一向十分重要,這樣在使用者離開網站後再回來時,網站就能還原使用者狀態。

最重要的考量因素並非「是否」儲存使用者狀態,而是「何時」儲存狀態。這一點非常重要,因為在捨棄分頁時,系統不會觸發任何事件,因此開發人員無法對捨棄分頁的情況做出反應。開發人員必須預先考量這項可能性,並做好準備。

儲存使用者狀態的最佳時機如下:

  • 狀態變更時定期執行。
  • 每次分頁進入背景時 (visibilitychange 事件)。

儲存狀態最糟糕的時機如下:

  • beforeunload 事件回呼中。
  • unload 事件回呼中。

這些是儲存狀態的糟糕時機,因為這些事件完全不可靠,且在許多情況下不會觸發,包括捨棄分頁時。

您可以參考網頁生命週期事件圖表,瞭解在網頁遭到捨棄時,系統會觸發哪些事件。如圖所示,分頁可以從「隱藏」狀態變更為「捨棄」狀態,且不會觸發任何事件。

網頁生命週期 API 狀態和事件流程。這份文件中所述狀態和事件流程的視覺化呈現。

事實上,只要網頁處於「隱藏」狀態,就無法保證在網頁遭到瀏覽器捨棄或使用者終止前,會觸發任何其他事件。因此,請務必在 visibilitychange 事件中儲存任何未儲存的使用者狀態,因為您可能不會再有其他機會。

以下程式碼概述了一些邏輯範例,可在每次目前使用者狀態變更時,將其排入佇列,或在使用者將分頁設為背景或離開時立即排入佇列:

let state = {};
let hasUnstoredState = false;

function storeState() {
  if (hasUnstoredState) {
    // Store `state` to localStorage or IndexedDB...
  }
  hasUnstoredState = false;
}

export function updateState(newState) {
  state = newState;
  hasUnstoredState = true;
  requestIdleCallback(storeState);
}

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    storeState();
  }
});

偵測到分頁已遭到捨棄

如先前所述,系統無法偵測分頁即將遭到捨棄,但可以偵測使用者返回分頁並重新載入網頁後,該分頁是否遭到捨棄。在這些情況下,document.wasDiscarded 屬性會設為 true。

if (document.wasDiscarded) {
  // The page was reloaded after a discard.
} else {
  // The page was not reloaded after a discard.
}

如要瞭解使用者遇到這類情況的頻率,您可以設定分析工具來擷取這項資訊。

舉例來說,您可以在 Google Analytics 中設定自訂事件參數,藉此判斷網頁瀏覽次數中有多少百分比來自捨棄分頁:

gtag('config', 'G-XXXXXXXXXX', {
  was_discarded: document.wasDiscarded,
});

如果您是數據分析供應商,建議您考慮預設在產品中加入這個維度。

在記憶體節省模式下測試網站

您可以載入網頁,然後在另一個分頁或視窗中造訪 chrome://discards,藉此測試網頁如何處理遭到捨棄的情況。

chrome://discards UI 中,找出清單中要捨棄的分頁,然後按一下「動作」欄中的「緊急捨棄」

chrome://discards 使用者介面的螢幕截圖,顯示連結至棄置分頁的位置

這麼做會捨棄分頁,讓您重新查看分頁,並驗證重新載入的頁面是否會回到您離開時的狀態。

請注意,目前無法透過 webdriver 或 puppeteer 等測試工具自動捨棄分頁;不過,由於分頁捨棄和還原的運作方式與重新載入網頁幾乎相同,因此如果您在使用者流程中途重新載入網頁後,測試使用者狀態是否已還原,那麼在捨棄/還原作業中也可能會成功。兩者的主要差異在於,當分頁遭到捨棄時,beforeunloadpagehideunload 事件不會觸發,因此只要您不依賴這些事件保留使用者狀態,就可以使用重新載入功能來測試捨棄/還原行為。

省電模式

啟用省電模式後,Chrome 會降低螢幕的重新整理頻率,以節省電池電力,這會影響捲動和動畫的真實度,以及視訊影格速率。

一般來說,開發人員不需要採取任何行動即可支援節能模式。啟用此模式後,適用於動畫轉場效果requestAnimationFrame() 的 CSS 和 JavaScript API 會自動調整顯示器的螢幕更新率。

這個模式可能會發生問題的主要情況,是當網站使用以 JavaScript 為基礎的動畫,並假設所有使用者都有特定的刷新率。

舉例來說,如果您的網站使用 requestAnimationFrame() 迴圈,並假設在回呼之間會經過 16.67 毫秒,則啟用省電模式時,動畫的執行速度會變慢兩倍。

請注意,開發人員假設所有使用者的預設螢幕更新率為 60 Hz 一向有問題,因為許多目前的裝置並非如此。

測量螢幕刷新率

目前沒有專用網頁 API 可用來測量螢幕更新率,因此一般來說,不建議使用目前的 API 進行測量。

開發人員使用現有 API 時,最好的做法是比較連續 requestAnimationFrame() 回呼之間的時間戳記。雖然這在大多數情況下可用於估算指定時間點的螢幕更新率,但無法讓您得知螢幕更新率何時變更。為此,您必須持續執行 requestAnimationFrame() 輪詢,但這會違背為使用者節省電力或延長電池續航力的目標。

在節能模式下測試網站

如要在節能模式下測試網站,您可以透過在 Chrome 設定中啟用節能模式,並將其設為在裝置未連接電源時執行。

如果沒有可拔除電源的裝置,也可以按照下列步驟手動啟用這項模式:

  1. 啟用 chrome://flags/#battery-saver-mode-available 旗標。
  2. 前往 chrome://discards,然後按一下「切換省電模式」連結 (重要事項:必須啟用 #battery-saver-mode-available 標記,連結才能運作)。

chrome://discards 使用者介面的螢幕截圖,顯示啟用省電模式的連結位置

啟用後,您可以與網站互動,確認所有內容是否正常顯示,例如動畫和轉場效果是否以預期速度執行。

摘要

雖然 Chrome 的記憶體節省模式和節能模式主要面向使用者,但如果處理不當,可能會對造訪網站的使用者體驗造成負面影響,因此對開發人員而言仍有影響。

一般來說,這些新模式的設計理念是參考現有的開發人員最佳做法。如果開發人員一直遵循長期的最佳網頁做法,他們的網站應該會繼續在這些新模式下正常運作。

不過,如果您的網站含有本文提及的任何做法,使用者可能會遇到問題,而啟用這兩種模式只會讓問題變得更嚴重。

如往常,要確認您提供的體驗是否優質,最好的方法就是以與使用者相符的條件測試網站。