查找哪些导航被禁止使用 bfcache,以及原因。
添加到 PerformanceNavigationTiming
类中的 notRestoredReasons
属性会报告文档中是否存在的帧在导航时被阻止使用 bfcache,以及原因。开发者可以使用这些信息来确定哪些网页需要更新以使其与 bfcache 兼容,从而提升网站性能。
当前状态
notRestoredReasons
API 已从 Chrome 123 开始提供,并正在逐步推出。
概念和用法
新式浏览器为历史记录导航提供了一项名为往返缓存 (bfcache) 的优化功能。这样,当用户返回到之前访问过的网页时,即可获得即时加载体验。网页可能会因各种原因而被阻止进入 bfcache,或者在 bfcache 中被驱逐,其中一些原因是规范要求的,一些原因则特定于浏览器实现。
以前,虽然有 Chrome 开发者工具中的测试,但开发者无法了解其网页在现场被禁止使用 bfcache 的原因。为了在现场启用监控功能,我们扩展了 PerformanceNavigationTiming
类,使其包含 notRestoredReasons
属性。这会返回一个对象,其中包含有关顶部框架和文档中所有 iframe 的相关信息:
- 被禁止使用 bfcache 的原因。
框架
id
和name
等详细信息,有助于识别 HTML 中的 iframe。这样,开发者就可以采取措施使这些网页与 bfcache 兼容,从而提升网站性能。
示例
PerformanceNavigationTiming
实例可以从 Performance.getEntriesByType()
和 PerformanceObserver
等功能中获取。
例如,您可以调用以下函数来返回效果时间轴中存在的所有 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。如需了解详情,请参阅弃用 unload 事件。response-cache-control-no-store
:该网页使用no-store
作为cache-control
值。related-active-contents
:该网页是从另一个网页(使用“复制标签页”)打开的,而该网页仍引用了此网页。
反馈
Chromium 团队希望了解您使用 bfcache notRestoredReasons
API 的体验。
请向我们说明 API 设计
API 是否有某些方面未按预期运行?或者,您是否缺少实现想法所需的方法或属性?对安全模型有疑问或意见?在相应的 GitHub 代码库中提交规范问题,或在现有问题中添加您的想法。
报告实现方面的问题
您是否发现了 Chromium 实现中的 bug?或者实现方式是否与规范不同?
请在我们的问题跟踪器上提交 bug。请务必提供尽可能详细的信息、简单的重现说明,并将组件指定为 UI > Browser > Navigation > BFCache
。故障非常适合分享快速简便的重现步骤。
显示对该 API 的支持
您打算使用 bfcache notRestoredReasons
API 吗?您的公开支持有助于 Chromium 团队确定功能的优先级,并向其他浏览器供应商表明支持这些功能的重要性。
使用 #NotRestoredReasons
标签向 @ChromiumDev 发送推文,告诉我们您在哪里以及如何使用该工具。