往返快取 notRestoredReasons API

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

Chris Mills
Chris Mills
Barry Pollard
Barry Pollard

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,並告訴我們您在哪裡使用它。

實用連結