监控 bfcache 阻止原因
PerformanceNavigationTiming.notRestoredReasons
属性报告了当前文档在导航时被阻止使用 bfcache 的原因。开发者可以使用此信息来识别需要更新的页面,以使其与 bfcache 兼容,从而提高网站性能。
后退/前进缓存 (bfcache)
现代浏览器提供了一种用于历史导航的优化功能,称为后退/前进缓存 (bfcache)。这使得用户返回之前访问过的页面时能够获得即时加载体验。页面可能会因各种原因被阻止进入 bfcache 或在 bfcache 中被逐出,其中一些是规范要求,另一些是浏览器实现特有的。
为了监控 bfcache 阻止原因,PerformanceNavigationTiming
类包含一个 notRestoredReasons
属性。它返回一个 NotRestoredReasons
对象,其中包含有关顶级框架和文档中所有 <iframe>
的相关信息。
- 阻止使用 bfcache 的原因。
- 诸如框架
id
和name
等详细信息,有助于识别 HTML 中的<iframe>
。
注意: 历史上,弃用的 PerformanceNavigation.type
属性用于监控 bfcache,开发者测试 type
是否为 "TYPE_BACK_FORWARD
" 以了解 bfcache 命中率。然而,这并没有提供 bfcache 阻止的任何原因或其他数据。从现在起,应使用 notRestoredReasons
属性来监控 bfcache 阻止。
记录 bfcache 阻止原因
可以使用 PerformanceObserver
获得持续的 bfcache 阻止数据,例如:
const observer = new PerformanceObserver((list) => {
let perfEntries = list.getEntries();
perfEntries.forEach((navEntry) => {
console.log(navEntry.notRestoredReasons);
});
});
observer.observe({ type: "navigation", buffered: true });
或者,可以使用诸如 Performance.getEntriesByType()
等合适的方法获得历史 bfcache 阻止数据。
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);
}
}
上面显示的代码片段将 NotRestoredReasons
对象记录到控制台。这些对象具有以下结构,它表示顶级框架的阻止状态。
{
children: [],
id: null,
name: null,
reasons: [
{ reason: "unload-listener" }
],
src: "",
url: "example.com",
}
属性如下所示:
children
只读 实验性-
一个
NotRestoredReasons
对象数组,每个对象对应当前文档中嵌入的一个子<iframe>
,其中可能包含与子框架相关的阻止顶级框架的原因。每个对象都具有与父对象相同的结构 - 这样,任何数量级别的嵌入<iframe>
都可以通过对象递归表示。如果框架没有子级,则数组为空;如果文档位于跨域<iframe>
中,则children
将返回null
。 id
只读 实验性-
一个字符串,表示包含文档的
<iframe>
的id
属性值(例如<iframe id="foo" src="...">
)。如果文档不在<iframe>
中或<iframe>
没有设置id
,则id
将返回null
。 name
只读 实验性-
一个字符串,表示包含文档的
<iframe>
的name
属性值(例如<iframe name="bar" src="...">
)。如果文档不在<iframe>
中或<iframe>
没有设置name
,则name
将返回null
。 reasons
只读 实验性-
一个
NotRestoredReasonDetails
对象数组,每个对象都表示导航页面被阻止使用 bfcache 的原因。如果文档位于跨域<iframe>
中,则reasons
将返回null
,但如果任何<iframe>
阻止了顶级框架使用 bfcache,则父文档可能会显示reason
为"masked"
。有关原因的更多详细信息,请参见 阻止原因。 src
只读 实验性-
一个字符串,表示包含文档的
<iframe>
的源路径(例如<iframe src="exampleframe.html">
)。如果文档不在<iframe>
中,则src
将返回null
。 url
只读 实验性-
一个字符串,表示导航页面或
<iframe>
的 URL。如果文档位于跨域<iframe>
中,则url
将返回null
。
报告同源 <iframe>
中的 bfcache 阻止
当页面嵌入同源 <iframe>
时,返回的 notRestoredReasons
值将包含一个对象数组,该数组位于 children
属性中,表示与每个嵌入框架相关的阻止原因。
例如:
{
children: [
{
children: [],
id: "iframe-id",
name: "iframe-name",
reasons: [],
src: "./index.html",
url: "https://www.example.com/iframe-examples.html"
},
{
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"
}
报告跨域 <iframe>
中的 bfcache 阻止
当页面嵌入跨域框架时,关于它们的共享信息量会受到限制,以避免泄露跨域信息。只包含外部页面已知的信息,以及跨域子树是否导致 bfcache 阻止。不包含任何阻止原因或关于子树较低级别(即使某些子级别是同源)的信息。
例如:
{
children: [
{
children: [],
id: "iframe-id",
name: "iframe-name",
reasons: [],
src: "https://www.example2.com/",
url: null
}
],
id: null,
name: null,
reasons: [
{ "reason": "masked" }
],
src: null,
url:"https://www.example.com"
}
对于所有跨域 <iframe>
,没有报告阻止原因;对于顶级框架,报告了一个 "masked"
原因,表示出于隐私目的隐藏了原因。请注意,"masked"
也可能用于隐藏特定于用户代理的原因;它并不总是表示 <iframe>
中存在问题。
阻止原因
阻止可能发生的原因有很多,浏览器可以选择根据其自身的操作方式实现自己的特定阻止原因。开发者应避免依赖特定原因的措辞,并准备好处理添加和删除的新原因。
规范中列出的初始值为:
"fetch"
-
在卸载时,当前文档发起的获取操作(例如,通过
fetch()
)在进行中被取消。因此,页面没有处于可以存储在 bfcache 中的稳定状态。 "lock"
-
在卸载时,持有的锁和锁请求被终止,因此页面没有处于可以存储在 bfcache 中的稳定状态。
"masked"
-
出于隐私目的,确切原因被隐藏。此值可以表示以下几种情况之一:
- 当前文档包含跨域
<iframe>
中的子级,它们阻止了存储在 bfcache 中。 - 当前文档无法因特定于用户代理的原因而存储在 bfcache 中。
- 当前文档包含跨域
-
创建当前文档的原始导航发生错误,并且阻止了将生成的错误文档存储在 bfcache 中。
"parser-aborted"
-
当前文档从未完成其初始 HTML 解析,并且阻止了将未完成的文档存储在 bfcache 中。
"websocket"
-
在卸载时,打开的 WebSocket 连接被关闭,因此页面没有处于可以存储在 bfcache 中的稳定状态。
一些浏览器可能会使用其他阻止原因,例如:
"unload-listener"
-
页面注册了一个
unload
处理程序,这会阻止使用 bfcache。这起到一个有用的警告作用,因为unload
已被弃用。有关更多信息,请参见 使用说明。 "response-cache-control-no-store"
-
该页面使用
no-store
作为Cache-Control
头部的值。 -
该页面从另一个仍然包含对该页面引用的页面打开,例如使用“重复标签”功能。
浏览器兼容性
BCD 表格仅在浏览器中加载
另请参见
注意: 本文改编自 Back/forward cache notRestoredReasons API by Chris Mills and Barry Pollard,最初发布于 developer.chrome.com
,发布于 2023 年,根据 知识共享署名 4.0 许可证。