往返缓存 notRestoredReasons API

查找哪些导航被阻止使用 bfcache 以及原因。

添加到 PerformanceNavigationTiming 类中的 notRestoredReasons 属性会报告有关文档中存在的帧是否被阻止在导航时使用 bfcache 以及原因的相关信息。开发者可以使用这些信息来识别需要更新的网页,使其与 bfcache 兼容,从而提升网站性能。

当前状态

步骤 状态
1. 创建铺垫消息 完成
2. 创建规范的初始草稿 尚未开始
3. 收集反馈并不断改进设计 进行中
4. 源试用 已开始
5. 发布 尚未开始

试用 bfcache notRestoredReasons API

从版本 109 开始,bfcache notRestoredReasons API 在 Chromium 中以源试用的形式提供。有关此功能的发布时间表的最新消息,请访问其 ChromeStatus.com 功能页面(请参阅 Chrome 路线图,了解版本发布日期)。

您可以注册参与源试用并在实验中使用 bfcache notRestoredReasons API。请参阅参与源试用,了解注册后如何使用令牌。

概念和用法

现代浏览器为历史记录导航提供了一种优化功能,称为往返缓存 (bfcache)。这样一来,当用户返回他们已访问的网页时,就可以获得即时加载体验。网页可能会因各种原因而被禁止进入 bfcache 或被逐出 bfcache,有些是规范要求提供的,有些则是针对浏览器实现方式的。

以前,尽管 Chrome 开发者工具中提供了一项测试,但开发者无法得知为何其网页无法在此字段中使用 bfcache。为了在该字段中启用监控功能,PerformanceNavigationTiming 类已扩展为包含一个 notRestoredReasons 属性。这将返回一个对象,其中包含文档中存在的所有帧的相关信息:

  • 框架 idname 等详细信息,有助于在 HTML 中识别它们。
  • 用户是否被禁止使用 bfcache。
  • 用户被禁止使用 bfcache 的原因。

    这样一来,开发者便可以采取相应措施,使这些网页与 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 属性会返回具有以下结构的对象,表示顶级框架的屏蔽状态:

{
  blocked: true,
  children: [],
  id: "",
  name: "",
  reasons: [ "Internal Error", "Unload handler" ],
  src: "",
  url: "a.com"
}

具体属性如下:

blocked
一个布尔值,用于指定是否禁止所浏览的网页使用 bfcache (true) (false)。
children
一个对象数组,表示顶层帧中嵌入的所有帧的屏蔽状态。每个对象都具有与父对象相同的结构,这样即可以递归方式在该对象内部表示任意数量的嵌入帧。如果帧没有子项,数组将为空。
id
一个字符串,表示帧的 id 属性值(例如 <iframe id="foo" src="...">)。如果帧没有 id,则值将为空字符串。
name
一个字符串,表示帧的 name 属性值(例如 <iframe name="bar" src="...">)。如果帧没有 name,则值将为空字符串。
reasons
一个字符串数组,其中每个字符串表示导航后的网页被禁止使用 bfcache 的原因。有多种原因可能会导致出现屏蔽。如需了解详情,请参阅下面的屏蔽原因部分。
src
表示帧来源路径的字符串(例如 <iframe src="b.html">)。如果帧没有 src,则值将为空字符串。
url
一个字符串,表示已导航页面的网址。

对于不代表历史记录导航的 PerformanceNavigationTiming 对象,notRestoredReasons 属性将返回 null。这有助于确定 bfcache 是否与特定导航无关;相反,notRestoredReasons 不受支持(如果它会返回 undefined)则非常有用。

报告同源帧中的 bfcache 阻塞

当某个网页嵌入了同源框架时,返回的 notRestoredReasons 值会在 children 属性内包含一个对象,该对象表示每个嵌入的框架的屏蔽状态。

例如:

{
  blocked: false,
  children: [
    { url: "a.com", src: "b.a.com", id: "b", name: "b", blocked: false, reasons: [], children: [] },
    { url: "a.com", src: "c.a.com", id: "c", name: "c", blocked: true, reasons: [ "BroadcastChannel" ], children: [] },
    { url: "a.com", src: "d.a.com", id: "d", name: "d", blocked: false, reasons: [], children: [] }
  ],
  id: "",
  name: "",
  reasons: [],
  src: "",
  url:"a.com"
}

报告跨源帧中的 bfcache 阻塞

如果网页中嵌入了跨源框架,我们会限制分享的跨源框架相关信息量,以免泄露跨源信息。我们只添加外部网页已知的信息,以及跨源子树是否阻止了 bfcache。我们不会添加任何屏蔽原因或子树较低级别的相关信息(即使某些子级来源是同源的)。

例如:

{
  blocked: false,
  children: [
    { url: "a.com", src: "c.a.com", id: "c", name: "c", blocked: true, reasons: [ "ScreenReader" ], children: [] },
    /* cross-origin frame */
    { url: "", src: "b.com", id: "d", name: "d", blocked: true, reasons: [], children: [] }
  ],
  id: "",
  name: "",
  reasons: [],
  src: "",
  url:"a.com"
}

如果多个跨源帧都有阻塞原因,我们会随机选择一个跨源 iframe,并报告其是否阻止了 bfcache。对于其余帧,我们针对 blocked 值报告 null。这是为了阻止作恶方在无法控制的网站上推断用户状态的相关信息,方法是将多个第三方框架嵌入到网页中,然后比较各个框架的屏蔽信息。

{
  blocked: false,
  children: [
    /* cross-origin frames */
    {url: "", src: "b.com", id: "b", name: "b", blocked: null, reasons: [], children: []},
    {url: "", src: "c.com", id: "c", name: "c", blocked: true, reasons: [], children: []},
    {url: "", src: "d.com", id: "d", name: "d", blocked: null, reasons: [], children: []}
  ]
  id: "",
  name: "",
  reasons: [],
  src: "",
  url:"a.com"
}

请参阅解释器中的安全和隐私权部分,详细了解安全和隐私权注意事项。

屏蔽原因

如前所述,有多种原因可能会导致出现屏蔽。我们编译了一个方便的电子表格,其中显示所有原因字符串并解释了其含义。

有几大类原因值得强调:

  • Circumstantial:表示屏蔽原因与开发者的网页代码不直接相关。例如,相关组件崩溃、加载进程出现问题、页面处于无法缓存的临时状态、由于内存不足而停用 bfcache,或者 Service Worker 对页面执行了导致页面无法缓存的操作。
  • Extensions:以下是与扩展程序相关的几个不同原因消息。通常,我们会将几个不同的原因合并为一个“扩展程序”原因。我们故意对与扩展程序相关的屏蔽原因含糊不清,因为我们不希望透露过多的信息,例如用户安装了哪些扩展程序、在网页上使用了哪些扩展程序、他们在做什么,等等。
  • PageSupportNeeded:开发者的代码正在使用一项网络平台功能,该功能原本不会 bfcache 阻塞,但当前处于 bfcache 阻塞状态。例如,网页当前具有包含已注册监听器的 BroadcastChannel,或者该网页处于打开的 IndexedDB 连接。或者,该网页注册了 unload 处理程序,该处理程序目前阻止在某些浏览器中使用 bfcache
  • SupportPending:开发者的代码使用了使网页不符合 bfcache 条件的网络平台功能,例如 Web Serial APIWeb Authentication APIFile System Access APIMedia Session API。或者,该网页使用了 Cache-Control: no-store,这目前会阻止在某些浏览器中使用 bfcache。此类别还用于报告网页外部存在阻止 bfcache 的工具,例如屏幕阅读器或 Chrome 密码管理工具。

反馈

Chromium 团队希望了解您使用 bfcache notRestoredReasons API 的体验。

向我们介绍 API 设计

是否存在 API 无法正常运行的某些问题?或者说,是否缺少某些方法或属性来实现您的想法?如果您对安全模型有疑问或意见,请在相应的 [GitHub 代码库][feedback] 中提交规范问题,或将您的想法添加到现有问题中。

报告实施方面的问题

您是否发现了 Chromium 实现中存在的错误?或者,实现方式是否不同于规范? 请在 new.crbug.com 提交 bug。请务必提供尽可能多的详情和有关重现的简单说明,并将组件指定为 UI > Browser > Navigation > bfcacheGlitch 非常适合快速轻松地分享重现的视频。

显示对该 API 的支持

您打算使用 bfcache notRestoredReasons API 吗?您的公开支持有助于 Chromium 团队确定功能的优先级,并向其他浏览器供应商表明支持这些功能的重要性。

请使用 # 标签 #NotRestoredReasons@ChromiumDev 发送一条推文,告诉我们您使用该产品的位置和方式。

实用链接