跳转到内容

前进后退缓存(bfcache):即时的前进后退导航

发布于

一句话: 根据 MDN,前进后退缓存(bfcache)是一项性能特性,它在用户离开页面时保存 该页面的完整快照——包括 JavaScript 堆——从而让浏览器在之后的前进或后退导航中即时恢复 它,而不必重复加载该页面所需的网络请求。

根据 MDN,普通的 HTTP 缓存条目只保存之前请求的响应;而 bfcache 保存的是内存中完整的 活动页面,用户离开时正在进行的代码会被暂停,返回时再恢复执行。根据 web.dev,这使得 bfcache 恢复比即便经过良好优化、依赖 HTTP 缓存的加载还要更快。

下面是包裹在存在性检查中的 pageshow,通过 event.persisted 区分 bfcache 恢复与正常加载:

if ('onpageshow' in window) {
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
console.log('此页面是从 bfcache 恢复的。');
} else {
console.log('此页面是正常加载的。');
}
});
} else {
// 针对不支持 pageshow 的浏览器的回退处理。
console.log('此页面是正常加载的。');
}

根据 web.dev,pageshow 会在首次加载页面时紧随 load 事件触发,并且在页面从 bfcache 恢复时再次触发;它的 persisted 属性用于区分这两种情况。

根据 web.dev,所有主流浏览器都包含 bfcache,其中 Chrome 自版本 96 起支持,Firefox 和 Safari 同样支持。

  • unload 监听器可能阻止 bfcache 可用性。 根据 MDN,某些代码特性——MDN 举出的 例子是 unload 事件处理程序——与 bfcache 不兼容,其存在可能阻止页面被缓存。根据 web.dev,具体而言,这会使页面在桌面版 Chrome 和 Firefox 中不符合缓存条件,而 Safari 仍可能缓存这类页面,移动版 Chrome 和 Safari 也可能尝试缓存。根据 web.dev, 推荐的替代方案是 pagehide,它会在 unload 原本会触发的每种情况下触发,并且还会 在页面进入 bfcache 时触发。
  • 待处理任务会被暂停,而非取消。 根据 MDN,页面被存入缓存时,正在进行的 JavaScript 会被暂停,恢复时再继续执行——代码不应假设定时器或正在进行的 promise 会 在页面不可见期间持续运行。
  • bfcache 恢复不是一次全新的页面加载。 由于 pageshow 可能在没有前置 load 事件的情况下触发,只在 load 监听器中刷新过期或敏感 UI 状态的代码会错过一次恢复; 应检查 event.persisted 并在那里同样更新或重新获取该状态。
  • 用监测阻塞原因取代猜测。 根据 MDN, PerformanceNavigationTiming.notRestoredReasons API 会报告某次特定导航为何未从 bfcache 恢复,这比单凭行为推断原因更可靠。
  • 核心网页指标 —— bfcache 恢复在核心 网页指标报告工具中会被计为独立的一次页面访问。
  • 推测规则 API —— 本站的另一篇 性能参考文档。