为 Cache-Control: no-store 启用 bfcache

Chrome 将进行一项更改,以允许在安全的情况下为使用 Cache-Control: no-store 的网页使用往返缓存 (bfcache)。了解这对开发者意味着什么。

背景

Cache-Control: no-store 设为 HTTP 标头即表示相应网页不应存储在 HTTP 缓存中。此指令应用于包含敏感数据的网页(例如,用户登录后的网页),但 no-store 指令通常用于不包含敏感数据的网页。

使用 bfcache 时,我们会推迟销毁网页,并暂停 JS 执行,而不是在用户离开时销毁网页。如果用户很快返回,我们会让网页重新显示并取消暂停 JS 执行。这会为用户带来近乎即时的网页导航体验。

虽然 HTML 规范并未要求这样做,但浏览器通常会将 Cache-Control: no-store 视为一种信号,以避免将网页放入 bfcache 中。这是 bfcache 未被使用的最主要原因,在移动设备上,大约有 17% 的历史记录导航会出现这种情况,在桌面设备上,则有 7% 的历史记录导航会出现这种情况。这意味着,这些网页无法受益于快速恢复功能,而必须完全重新加载网页,包括所有网络调用、JavaScript 执行和呈现。

通常,设置 Cache-Control: no-store 是为了避免在网站发生变化时出现缓存问题,但在使用 bfcache 时,这个原因不太相关,因为整页恢复几乎就像一直处于打开状态一样。

Chrome 如何更改此行为

Chrome 已宣布有意改变此行为,但正在采取谨慎的态度来实施。自 Chrome 116 起,我们就一直在开展实验,直到最近,这些实验仅针对 5% 的网页加载进行。

我们于 10 月 2 日将此比例提高到了 10%,并计划在 11 月将其进一步提高到 20%,在明年年初将其提高到 50%,之后不久便会全面推出该功能,下文将介绍特定的停用选项。

敏感数据

虽然我们的分析表明,大部分后退或前进导航都不包含敏感数据,因此应符合 bfcache 的使用条件,但在某些情况下,网页不应放置在 bfcache 中。例如,退出时,应该无法再通过来回导航来检索登录页。

为避免这种情况,Chrome 会在 Cookie 或其他授权方法发生更改时,从 bfcache 中驱逐网页。

此外,如果对使用 Cache-Control: no-store 的网页使用以下 API,则这些网页不符合使用 bfcache 的条件:

请注意,此处并未详尽列出禁止使用 bfcache 的 API,而是禁止在 Cache-Control: no-store 页面上使用 bfcache,即使在用户离开网页时并未使用这些 API。

Cache-Control: no-store 网页的 bfcache 超时时间也缩短到了 3 分钟(不使用 Cache-Control: no-store 的网页的超时时间为 10 分钟),以进一步降低风险。

选择退出企业版

企业通常拥有难以更新的软件和共用设备。您可以停用 AllowBackForwardCacheForCacheControlNoStorePageEnabled 政策,以继续阻止对 Cache-Control: no-store 网页使用 bfcache。

测试更改

开发者可以使用以下标志测试此更改:

--enable-features=CacheControlNoStoreEnterBackForwardCache:level/restore-unless-cookie-change

如果上述任何例外情况适用(例如 Cookie 发生变化),则会导致网页无法使用 bfcache,并在 Chrome 开发者工具 bfcache 测试工具中显示“主资源包含 Cache-Control: no-store 的网页无法进入往返缓存”这一原因。

您可以使用此 bfcache 测试页测试有无此标记。

开发者应知

虽然开发者无需为用户进行任何更改,即可受益于更高的 bfcache 使用量,但他们可能需要考虑一些事项。其他网站在 2021 年 12 月 bfcache 首次发布时可能也遇到过类似问题。

对性能的影响

我们做出这一调整是为了改善网络用户的网页体验。我们在首次推出 bfcache 时就发现核心 Web 指标有了明显改善,现在我们希望将同样的改进推广到更多网站。

随着此功能的推出,网站所有者可能会发现其核心网页指标有所提升,并且可以在 CrUX(包括 CrUX 信息中心)中衡量 bfcache 使用情况

影响分析

从 bfcache 恢复的网页会“恢复”旧网页(包括 JavaScript 堆),而不是重新加载网页。许多热门分析服务提供商不会将 bfcache 恢复计为新的网页浏览,因为它们仅在首次加载时触发网页浏览。

因此,网站在首次开始使用 bfcache 时,其 Google Analytics 中的网页加载次数可能会有所减少。我们建议您为 pageshow 事件设置监听器并检查 persisted 属性,以将这些事件视为网页浏览:

// Send a pageview when the page is first loaded.
gtag('event', 'page_view');

// Send another pageview if the page is restored from bfcache.
window.addEventListener('pageshow', (event) => {
  if (event.persisted) {
    // Page was restored from bfcache, sent another page view.
    gtag('event', 'page_view');
  }
});

处理网页恢复时的更新

现在,如果网站以前未看到 bfcache 使用量,以及当网页完全重新加载新数据时,开发者可能需要考虑在 bfcache 恢复时刷新数据。

触发更新的方式与使用 pageshow 事件记录额外的网页浏览次数并检查 persisted 属性的方式类似。

请注意,并非所有内容都需要更新,用户可能更希望“返回”他们之前看到的内容。例如,刷新文章列表可能会导致用户看不到他们打算回头查看的文章。

对广告的影响

与分析影响类似,如果广告仅在网页加载时加载,网站可能会出现广告展示次数减少的情况。您可以使用 pageshow 事件并检查 persisted 属性,在 bfcache 恢复时以编程方式刷新广告,以确保与完整网页加载保持一致,但这不一定是正确的做法。如需了解如何触发广告重新加载,请参阅广告提供商的文档。

有关 bfcache 的更多信息

如需详细了解 bfcache,请参阅我们的全面 bfcache 技术指南

反馈

我们热切希望收到有关此变更的反馈,您可以在使用 bfcache 组件的 Chrome 问题跟踪器中提供反馈意见。

总结

我们很高兴能够将 bfcache 的优势推广到更多网页,从而为用户改善网页体验。我们仔细考虑了这项变更,并力求以尽可能安全的方式进行实施。我们希望此处提供的信息能帮助开发者了解这项变更,并做出必要的更改,以免在发生这种情况时出现问题。