为 Cache-Control: no-store 启用 bfcache

发布时间:2024 年 10 月 21 日;上次更新时间:2025 年 9 月 9 日

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

背景

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

借助 bfcache,当用户离开网页时,我们不会销毁网页,而是会延迟销毁并暂停 JavaScript 执行。如果用户很快返回,我们会再次显示该网页并取消暂停 JavaScript 执行。这样一来,用户几乎可以即时完成网页导航。

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

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

Chrome 如何更改此行为

Chrome 已宣布打算更改此行为,但会谨慎地进行此更改。自 Chrome 116 以来,我们一直在进行实验,逐步提高页面加载的百分比,预计在 2025 年 3 月和 4 月达到 100%。

敏感数据

虽然我们的分析表明,大多数后退或前进导航不包含敏感数据,因此应符合 bfcache 的条件,但有些情况下网页不应放置在 bfcache 中。例如,在退出登录后,不应再能通过前进或后退来检索已登录的页面。

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

此外,对于使用 Cache-Control: no-store 的网页,使用以下 API 仍会导致这些网页无法储存至往返缓存:

请注意,这并非会阻止使用 bfcache 的 API 的完整列表,而是指即使在离开网页时未被使用,也会在 Cache-Control: no-store 网页上阻止使用 bfcache 的 API。

Cache-Control: no-store 页面的往返缓存超时时间也缩短为 3 分钟(未使用 Cache-Control: no-store 的页面为 10 分钟),以进一步降低风险。

企业版退出选项

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

测试变更

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

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

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

您可以使用此 bfcache 测试网页来测试启用和未启用此标志的情况。

开发者应了解的事项

虽然开发者无需进行任何更改,用户即可受益于这种更广泛的 bfcache 用法,但开发者可能需要考虑以下几点。其他网站在 2021 年 12 月首次推出 bfcache 时可能也遇到了类似的问题。

开发者是否仍应尽量减少 Cache-Control: no-store 的使用?

在上述有限的情况下,bfcache 针对 Cache-Control: no-store 启用,且仅适用于 Chrome。使用 Cache-Control: no-store 时,其他浏览器可能仍会阻止使用 bfcache。

最佳实践仍然是尽量减少使用 Cache-Control: no-store,而不是依赖这些启发法。

对性能的影响

我们之所以做出此项更改,是为了改善网页上的用户体验。我们首次推出 bfcache 时,发现 Core Web Vitals 指标有了显著改进,现在我们希望将这些改进带给更多网站。

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

影响分析

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

因此,网站在首次开始使用 bfcache 时,可能会发现其分析中的网页加载次数有所减少。我们建议您将这些事件视为网页浏览,方法是为 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 属性来记录其他网页浏览次数以进行分析类似。

请注意,并非所有内容都需要更新,用户可能更喜欢“返回”到之前看到的内容。例如,刷新文章列表可能意味着用户无法再看到他们之前想回去查看的文章。

对广告的影响

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

有关 bfcache 的更多信息

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

反馈

我们非常期待收到有关此变更的反馈,您可以在 Chrome 的问题跟踪器中使用 bfcache 组件提供反馈。

总结

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