使用擴充訊息通訊埠的 BFCache 行為變更

Mingyu Lei
Mingyu Lei

往返快取 (或 BFCache) 是一種瀏覽器最佳化功能,能讓使用者迅速往返網頁,我們正在修改 Chrome BFCache,這可能會影響使用訊息通訊埠的擴充功能。如果您擁有的 Chrome 擴充功能會使用訊息在內容指令碼和擴充功能之間進行通訊,請繼續閱讀,瞭解如何測試及調整擴充功能。

擴充訊息連接埠

擴充功能會透過訊息傳遞功能與內容指令碼或其他擴充功能進行通訊。您可以呼叫 runtime.sendMessage()tabs.sendMessage(),或使用可重複使用的訊息通訊端,透過一次性要求傳送訊息。只要通訊埠處於有效狀態,內容指令碼和擴充功能背景指令碼就能重複使用通訊埠,彼此發布訊息。

詳情請參閱「訊息傳遞」。

往返快取

當使用者離開可使用 BFCache 的網頁時,瀏覽器會允許網頁及其所有狀態保留在記憶體中,但處於非完全啟用狀態。如果使用者執行歷史記錄導覽 (返回或前進) 至快取的網頁,瀏覽器會嘗試從 BFCache 還原網頁。這樣可加快導覽速度,並改善使用者的瀏覽體驗。

當網頁處於 BFCache 時,會處於凍結狀態,無法執行 JavaScript。這表示無法處理收到的訊息。

詳情請參閱「往返快取」。

擴充功能訊息端口對 BFCache 的影響

簡單來說,擴充功能將訊息傳送至 BFCache 中的網頁,可能會導致快取遭到淘汰,進而影響效能。

如果含有開放式擴充功能訊息通訊埠的網頁儲存在 BFCache 中,該通訊埠會保持開啟狀態。一旦從 BFCache 還原網頁,擴充功能服務 worker 仍可使用訊息通訊埠的舊參照,將訊息發布至內容指令碼。

不過,如果擴充功能嘗試在網頁仍在 BFCache 中時,透過該訊息埠發布訊息,由於處理常式已凍結,因此訊息會傳送但無法完全送達。擴充功能很難判斷並解決這種情況,因為排入佇列和捨棄訊息都會產生問題。

為避免發生訊息遺失的問題,Chrome 目前的實作方式是從 BFCache 中移除主機網頁,並捨棄訊息。如果使用者返回該網頁,系統會重新載入網頁,讓擴充功能設定新的連線。

另一方面,這項實作會限制 BFCache 適用的情況,進而限制效能提升,特別是對於使用廣播或心跳機制的擴充功能,因為這類擴充功能會定期傳送訊息給所有連線。此外,由於擴充功能會在傳送訊息給內容指令碼時觸發淘汰程序,因此網頁開發人員無法防止自己的網頁遭到淘汰。

為提升整體效能,我們打算推出新的訊息通訊端行為。

新行為:在網頁儲存在 BFCache 時關閉訊息管道

從 Chrome 123 開始,當含有開放式擴充功能訊息連接埠的網頁儲存在 BFCache 中時,基礎訊息管道會從內容指令碼端主動關閉。因此,所有訊息端口都會關閉,擴充功能會收到 onDisconnect 事件。

由於管道已關閉,因此在網頁處於 BFCache 狀態時,系統不會傳送任何訊息。因此,頁面不會因擴充功能而遭到淘汰。

即使網頁已從 BFCache 還原,關閉的訊息管道也不會重新開啟。擴充功能作者建議的做法是監聽網頁生命週期事件,並在從 BFCache 還原網頁時設定新的連線,如以下範例所示。

// content script

let port;

window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // The page is restored from BFCache, set up a new connection.
    port = chrome.runtime.connect();
  }
});

請參閱不同瀏覽器代表的 WECG 對話 (在問題 474 下方) 進一步瞭解相關資訊。

我會受到影響嗎?

新的行為會在 Chrome 123 中透過標記提供,方便您測試程式碼。詳情請參閱時間表。請按照下列步驟測試擴充功能。請注意,這項功能只提供簡單的測試,我們建議您啟用這項功能一段時間後再執行 Chrome,因為很難預測擴充功能中的哪些功能可能會導致問題。

測試新行為

如要在 Chrome 123 中強制啟用實驗功能,請按照下列步驟操作:

  1. 使用下列標記啟動 Chrome,強制執行行為:

    --enable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  2. 前往網頁,並視需要與擴充功能互動,讓內容指令碼開啟擴充功能的通訊埠。

  3. 離開並返回。頁面現在應已還原,但內容指令碼和服務工作者之間的訊息管道應已中斷。

  4. 測試擴充功能是否仍可正常運作,如果無法運作,請按照上一節所述手動重新連線。

使用舊版行為找出簡單問題

在這個變更之前,如果您嘗試將訊息傳送至與 bfcache 中網頁相關聯的連接埠,Chrome 會顯示警告。這項功能可用於找出部分與背景傳送至網頁的訊息相關問題,但並非所有問題都能找出。

  1. 請確認 Chrome 版本至少為 123。建議您使用 Chrome Canary,因為該版本會顯示額外警告,讓測試作業更輕鬆。
  2. 使用下列標記啟動 Chrome,強制執行舊版行為:

    --disable-features=DisconnectExtensionMessagePortWhenPageEntersBFCache
    
  3. 前往可使用 BFCache 的網頁 (例如 https://example.com/ 等簡單網站),請按照 BFCache 教學課程操作,確保資料是從 BFCache 還原。

  4. 安裝並啟用擴充功能,然後再次測試 BFCache 資格。您可以手動離開頁面,等待擴充功能將訊息發布到 BFCached 頁面,然後再返回該頁面。

  5. 如果系統因清除作業而必須重新載入網頁,而非從 BFCache 載入,且導致無法還原的問題是「ExtensionSentMessageToCachedFrame」,則擴充功能可能會受到這項異動的影響。

    在 Chrome Canary 124.0.6315.0 以上版本中,您也會在頁面中看到以下警告:

    未從 BFCache 還原網頁時顯示的警告。
    如果無法從 BFCache 還原網頁,系統會顯示警告。

確認擴充功能已將訊息發布至 BFCache 頁面後,您可以按照前一個部分的步驟強制啟用實驗,並觀察是否有任何邏輯中斷情形。

發布時間表

我們預計從 Chrome 123 開始,逐步實施新機制。詳細計畫如下:

日期 預計里程碑
2 月 15 日 在 Chrome 123 Canary 和開發人員版中,開始針對新行為進行實驗。
3 月 7 日 在 Chrome 123 Beta 版中開始新行為的實驗。
3 月 18 日 將新行為發布給 Chrome 123 穩定版的 4% 使用者。
3 月 25 日 將新行為發布給 Chrome 123 穩定版的 50% 使用者。
4 月 2 日 實驗結束後,系統會將新行為設為預設。