找出哪些導覽遭封鎖而無法使用 bfcache,以及原因。
加入 PerformanceNavigationTiming 類別的 notRestoredReasons 屬性會回報資訊,說明文件中的影格是否因導覽而無法使用 bfcache,以及原因。開發人員可以運用這項資訊找出需要更新的網頁,使其與 bfcache 相容,進而提升網站效能。
目前狀態
notRestoredReasons API 已在 Chrome 123 中發布,並逐步推出。
概念和用途
新式瀏覽器提供名為「往返快取」(bfcache) 的最佳化功能,可提升瀏覽記錄的導覽體驗。這樣一來,使用者返回先前造訪過的網頁時,就能立即載入網頁。網頁可能因各種原因無法進入 bfcache,或在 bfcache 中遭到逐出,有些原因符合規格要求,有些則與瀏覽器實作方式有關。
先前,開發人員無法得知網頁在實際環境中無法使用 bfcache 的原因,但 Chrome 開發人員工具中提供測試。如要在欄位中啟用監控功能,請擴充 PerformanceNavigationTiming 類別,加入 notRestoredReasons 屬性。這會傳回一個物件,其中包含頂端影格和文件中所有 iframe 的相關資訊:
- 他們無法使用 bfcache 的原因。
例如影格
id和name,有助於找出 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處理常式,導致特定瀏覽器無法使用往返快取。詳情請參閱「淘汰卸載事件」。response-cache-control-no-store:網頁使用no-store做為cache-control值。related-active-contents:網頁是從其他網頁開啟 (使用「複製分頁」),且其他網頁仍參照這個網頁。
意見回饋
Chromium 團隊想瞭解您使用 bfcache notRestoredReasons API 的體驗。
介紹 API 設計
API 是否有任何不符合預期的地方?或者,是否有缺少的屬性或方法,導致您無法實作想法?對安全模型有任何問題或意見嗎?在對應的 GitHub 存放區中提出規格問題,或在現有問題中新增想法。
回報導入問題
您是否發現 Chromium 實作有錯誤?還是實作方式與規格不同?
在問題追蹤工具中回報錯誤。請務必盡可能提供詳細資料、重現問題的簡單操作說明,並指定元件為 UI > Browser > Navigation > BFCache。
支援 API
您打算使用 bfcache notRestoredReasons API 嗎?您的公開支持有助於 Chromium 團隊優先處理功能,並向其他瀏覽器供應商展現支援這些功能的重要性。
使用主題標記 #NotRestoredReasons 傳送推文給 @ChromiumDev,告訴我們您在何處使用這項功能,以及使用方式。