往返快取 notRestoredReasons API

查看哪些瀏覽功能遭到封鎖,無法使用 bfcache 及其原因。

PerformanceNavigationTiming 類別中加入 notRestoredReasons 屬性,會回報文件中的影格是否遭到封鎖,無法對導覽使用 bfcache 以及原因。開發人員可以根據這項資訊找出需要更新的網頁,讓網頁與 bfcache 相容,進而提高網站效能。

目前狀態

notRestoredReasons API 已從 Chrome 123 推出,將逐步推出。

概念和用法

新式瀏覽器提供往返快取 (bfcache) 的記錄導覽功能最佳化功能。以便在使用者返回造訪過的網頁時立即載入網頁。網頁可能基於各種不同原因而遭到封鎖,無法在 bfcache 中進入,或因各種原因而遭到撤銷,部分原因在於規格要求,以及瀏覽器的實作情況。

先前在 Chrome 開發人員工具中進行測試後,開發人員無法得知系統為何禁止自家網頁使用 bfcache 參數。為了在欄位中啟用監控功能,PerformanceNavigationTiming 類別已擴充為包含 notRestoredReasons 屬性。此方法會傳回一個物件,其中包含上頁框與文件中顯示的所有 iframe 的相關資訊:

  • 禁止使用 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,我們都會回報影格的 reasonsnull,頂層頁框則會顯示 "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,並告訴我們您在哪裡使用它。

實用連結