前进后退缓存(bfcache):即时的前进后退导航
发布于
一句话: 根据 MDN,前进后退缓存(bfcache)是一项性能特性,它在用户离开页面时保存 该页面的完整快照——包括 JavaScript 堆——从而让浏览器在之后的前进或后退导航中即时恢复 它,而不必重复加载该页面所需的网络请求。
为何比 HTTP 缓存更快
Section titled “为何比 HTTP 缓存更快”根据 MDN,普通的 HTTP 缓存条目只保存之前请求的响应;而 bfcache 保存的是内存中完整的 活动页面,用户离开时正在进行的代码会被暂停,返回时再恢复执行。根据 web.dev,这使得 bfcache 恢复比即便经过良好优化、依赖 HTTP 缓存的加载还要更快。
特性检测与回退
Section titled “特性检测与回退”下面是包裹在存在性检查中的 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.notRestoredReasonsAPI 会报告某次特定导航为何未从 bfcache 恢复,这比单凭行为推断原因更可靠。