为 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,即使在离开页面时未使用这些 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 时就发现 Core Web Vitals 有了明显的改进,现在,我们希望将同样的改进推广到更多网站。

随着此功能的推出,网站所有者可能会发现其核心网页指标有所提升,并且可以在 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 的优势推广到更多网页,从而为用户改善网页体验。我们仔细考虑了这项变更,并力求以尽可能安全的方式进行实施。我们希望此处提供的信息能帮助开发者了解这项变更,并做出必要的更改,以免在发生这种情况时出现问题。