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

Chrome 108 推出兩種全新模式:「記憶體節省模式」和「節能模式」,可讓使用者進一步控管 Chrome 使用系統資源的方式。

雖然這些新模式主要是供使用者使用,但網頁程式開發人員也必須留意這點,因為這可能會影響網站的使用者體驗。

本文將說明這些新模式可能帶來的影響,以及網頁程式開發人員可採取的行動,確保他們盡可能提供最佳體驗。

記憶體節省模式

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

捨棄分頁後,其標題和網站小圖示仍會顯示在分頁列上,但網頁本身會消失,就像一般關閉分頁一樣。如果使用者再次造訪該分頁,系統會自動重新載入頁面。

如果網頁單純是內容頁面,那麼捨棄並重新載入分頁可能不會影響使用者體驗,但對於內容豐富的互動式網站,且使用者操作起來較為複雜,如果網站不能將使用者還原到上次離開的地方,可能會在流程中央重新載入很令人困擾。

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 使用者介面中,您可以找到清單中要捨棄的分頁,然後按一下「動作」欄中的「緊急捨棄」

chrome://discards UI 的螢幕截圖,顯示捨棄分頁的連結位置

系統會捨棄該分頁,方便您再次造訪,並確認網頁重新載入的狀態與離開時的狀態相同。

請注意,目前無法透過 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 UI 的螢幕截圖,顯示啟用節能模式的連結位置

啟用後,您就可以與網站互動,確認一切運作正常,例如動畫和轉場效果能以所需速度執行。

摘要

雖然 Chrome 的記憶體節省模式和節能模式主要是面向使用者的功能,但若未妥善處理,可能會對開發人員造成負面影響。

一般而言,這些新模式的設計是考量到開發人員現有的最佳做法。如果開發人員持續遵循長久以來的網頁最佳做法,他們的網站應能繼續支援這些新模式。

不過,如果您的網站包含本文所述的任何做法,很可能是因為使用者遭遇的問題只會在啟用這兩種模式的情況下增加。

一如既往,要確保提供良好的體驗,最好的方法就是根據使用者的條件來測試您的網站。