往返快取 notRestoredReasons API

找出哪些導覽遭到封鎖,以及原因。

notRestoredReasons 屬性已新增至 PerformanceNavigationTiming 類別,可回報資訊,說明文件中的框架是否遭到封鎖,無法在導覽時使用 bfcache,以及封鎖的原因。開發人員可以利用這項資訊,找出需要更新的網頁,讓網頁與 bfcache 相容,進而提升網站效能。

目前狀態

notRestoredReasons API 已在 Chrome 123 中推出,並正在逐步推出。

概念和用法

現代瀏覽器為瀏覽記錄導覽提供最佳化功能,稱為「往返快取」 (bfcache)。這樣一來,使用者返回已造訪的網頁時,就能享有即時載入體驗。網頁可能會因為各種原因而遭到封鎖,無法進入 bfcache,或是在 bfcache 中遭到淘汰,其中有些是規格要求,有些則是瀏覽器實作方式的特定要求。

過去,開發人員無法得知為何自己的網頁無法在該欄位使用 bfcache,雖然可以在 Chrome 開發人員工具中進行測試。為在現場啟用監控功能,PerformanceNavigationTiming 類別已擴充為包含 notRestoredReasons 屬性。這個方法會傳回一個物件,其中包含頂層框架和文件中所有內嵌框架的相關資訊:

  • 使用者遭禁止使用 bfcache 的原因。
  • 詳細資料 (例如框架 idname),協助識別 HTML 中的 iframe。

    這可讓開發人員採取行動,讓這些網頁與 bfcache 相容,進而改善網站效能。

範例

您可以從 Performance.getEntriesByType()PerformanceObserver 等功能取得 PerformanceNavigationTiming 例項。

舉例來說,您可以叫用下列函式,傳回效能時間軸中顯示的所有 PerformanceNavigationTiming 物件,並記錄其 notRestoredReasons

function returnNRR() {
  const navEntries = performance.getEntriesByType("navigation");
  for (let i = 0; i < navEntries.length; i++) {
    console.log(`Navigation entry ${i}`);
    let navEntry = navEntries[i];
    console.log(navEntry.notRestoredReasons);
  }
}

針對瀏覽記錄導覽,PerformanceNavigationTiming.notRestoredReasons 屬性會傳回具有下列結構的物件,代表頂層框架的封鎖狀態:

{
  children: [],
  id: null,
  name: null,
  reasons: [
    {"reason", "unload-listener"}
  ],
  src: null,
  url: "https://www.example.com/page/"
}

屬性如下:

children
物件陣列,代表嵌入頂層影格中的任何同源影格的封鎖狀態。每個物件都與父項物件具有相同的結構,因此可在物件中遞迴表示任意數量的嵌入影格層級。如果影格沒有子項,陣列就會是空的。
id
字串,代表影格 id 屬性值 (例如 <iframe id="foo" src="...">)。如果影格沒有 id,則值為 null。對於頂層頁面,則為 null
name
字串,代表影格 name 屬性值 (例如 <iframe name="bar" src="...">)。如果影格沒有 name,則值為空字串。對於頂層頁面,則為 null
reasons
字串陣列,每個字串都代表導覽網頁遭到封鎖,無法使用 bfcache 的原因。導致封鎖的情況有很多種,詳情請參閱「封鎖原因」一節。
src
字串,代表影格來源的路徑 (例如 <iframe src="b.html">)。如果影格沒有 src,則值會是空字串。對於頂層頁面,則為 null
url
代表導向頁面/iframe 的網址的字串。

如果 PerformanceNavigationTiming 物件不代表瀏覽記錄導覽,notRestoredReasons 屬性會傳回 null

請注意,如果沒有封鎖原因,notRestoredReasons 也會傳回 null,因此 null 並非 bfcache 是否已使用的指標。為此,您必須使用 event.persisted 屬性

回報在同源框架中封鎖的 bfcache

如果網頁嵌入相同來源的框架,則傳回的 notRestoredReasons 值會在 children 屬性中包含物件,代表每個嵌入框架的封鎖狀態。

例如:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example.com/"
    },
    {
      children: [],
      id: "iframe-id2",
      name: "iframe-name2",
      reasons: [
        {"reason": "unload-listener"}
      ],
      src: "./unload-examples.html",
      url: "https://www.example.com/unload-examples.html"
    },
  ],
  id: null,
  name: null,
  reasons: [],
  src: null,
  url:"https://www.example.com"
}

回報跨來源框架中的 bfcache 封鎖

如果網頁嵌入跨來源框架,我們會限制分享的資訊量,避免洩漏跨來源資訊。我們只會納入外層網頁已知的資訊,以及跨來源子網是否封鎖 bfcache。我們不會提供任何封鎖原因或子樹狀圖較低層級的相關資訊 (即使部分子層級為相同來源)。

例如:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example2.com/"
    }
  ],
  id: null,
  name: null,
  reasons: [
        {"reason": "masked"}
  ],
  src: null,
  url:"https://www.example.com"
}

對於所有跨來源 iframe,我們會針對影格的 reasons 值回報 null,而頂層影格會顯示 "masked" 的原因。請注意,"masked" 也可能會因使用者代理程式而使用,因此不一定表示 iframe 有問題。

如要進一步瞭解安全性和隱私權注意事項,請參閱說明中的「安全性和隱私權」一節。

封鎖原因

如前所述,導致封鎖的因素有很多:

以下列舉幾個無法使用 bfcache 的常見原因:

  • unload-listener:網頁註冊 unload 處理常式,可防止在特定瀏覽器中使用 bfcache。詳情請參閱「淘汰卸載事件」。
  • response-cache-control-no-store:網頁使用 no-store 做為 cache-control 值。
  • related-active-contents:網頁是從另一個網頁開啟的 (使用「複製分頁」),且該網頁仍有此網頁的參照內容。

意見回饋

Chromium 團隊希望瞭解您使用 bfcache notRestoredReasons API 的體驗。

請告訴我們 API 設計

API 是否有任何功能無法正常運作?或者,您是否缺少實作想法所需的方法或屬性?對於安全性模型有任何問題或意見嗎?在對應的 GitHub 存放區中提出規格問題,或在現有問題中加入您的想法。

回報實作問題

您是否發現 Chromium 實作項目有錯誤?或者實作方式與規格不同?請在我們的 Issue Tracker 中回報錯誤。請務必盡可能提供詳細資訊,提供簡單的重現操作說明,並將元件指定為 UI > Browser > Navigation > BFCacheGlitch 可讓您輕鬆快速地分享重現內容。

顯示對 API 的支援

您打算使用 bfcache notRestoredReasons API 嗎?您公開表示的支持,有助於 Chromium 團隊將功能列為優先,並向其他瀏覽器供應商顯示,支援這些功能的重要性。

使用主題標記 #NotRestoredReasons 發送推文給 @ChromiumDev,告訴我們你在何處使用這項功能,以及使用方式。

實用連結