浏览器discard页面不可监听,只能通过pageshow.persisted===false、localStorage时间戳、URL标记及navigation.type交叉推断;可靠保存须在freeze或pagehide(persisted===true)中同步完成,还原需区分冷启动与bfcache热恢复。

浏览器主动回收(discarded)的页面无法被 JavaScript 捕获或干预——它发生时 JS 环境已彻底终止,所有监听器、定时器、beforeunload 全部失效。你唯一能做的,是在它发生前保存快照,并在用户重新打开时识别这是“冷启动”,再手动还原。
discarded 状态不可监听,只能靠 pageshow.persisted === false 推断
当用户从任务管理器切回一个被丢弃后重建的 Tab,浏览器会发起全新加载,此时触发 pageshow 事件,且 event.persisted === false。这不是“没缓存”,而是“这次不是从 bfcache 恢复”。你需要交叉验证:
- 检查
localStorage中是否存有上一次写入的标记,比如lastSaveTime;若距当前时间 > 5 分钟,大概率已被 discard(Frozen 通常撑不过 2–3 分钟) - 读取 URL 是否含
?_reloaded=1这类人工标记(需你在pagehide或freeze中主动写入) - 用
performance.getEntriesByType('navigation')[0]?.type判断导航类型:值为'reload'或'navigate'均可能对应 discard 后重建
真正能保存快照的时机只有 freeze 和 pagehide(persisted === true)
别等 discarded——它不可逆。可靠保存必须发生在 JS 还活着的时候:
-
freeze事件:移动端 Chrome、部分 Safari 触发,JS 将暂停但 DOM 仍在,此时可安全调用localStorage.setItem()或indexedDB写入 -
pagehide事件且event.persisted === true:Safari 更倾向走这条路,表示页面将进 bfcache;若此时还没保存过(比如frozen !== true),就补一次 - 避免在
freeze中做异步操作(如await localStorage.setItem()),它可能被中断;改用同步写法,或降级到sessionStorage
还原逻辑必须区分冷启动与热恢复
用户回到页面时,你要立刻判断是哪种场景:
- 冷启动(discard 后重建):
pageshow.persisted === false+document.hasFocus() === true+ 无残留 DOM 状态 → 从localStorage或服务端拉取最近快照,再手动 restore 表单值、window.scrollY、选中项等 - 热恢复(bfcache resume):
pageshow.persisted === true→ 不要重置状态,DOM 和事件监听器都还在,直接跳过初始化逻辑即可 - 还原时别读 DOM 引用(如
document.querySelector()),只读原始值:用input.value而非绑定整个节点,用window.scrollY而非element.scrollTop
最容易被忽略的是:discard 后重建没有“中间态”,它和普通刷新在 JS 层面完全等价。你不能指望任何事件或属性告诉你“我刚被杀过”,只能靠外部信号(时间戳、URL 标记、导航类型)拼出这个事实。一旦漏掉保存时机,或者还原时误判为热恢复,现场就永远丢了。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











