关于浏览器主动丢弃页面,你需要知道的几件事浏览器为了节省系统资源,会在后台标签页被挂起、系统内存不足时,主动“丢弃”某些页面。被丢弃的页面,所有 JavaScript 执行环境都将被彻底回收,包括之前保存的变量、DOM 状态、定时器——统统消失得干干净净。更棘手的是,页面被丢弃这件事,JavaScr
浏览器为了节省系统资源,会在后台标签页被挂起、系统内存不足时,主动“丢弃”某些页面。被丢弃的页面,所有 JavaScript 执行环境都将被彻底回收,包括之前保存的变量、DOM 状态、定时器——统统消失得干干净净。更棘手的是,页面被丢弃这件事,JavaScript 完全无法感知,开发者没有任何机会在那一刻做任何操作。说白了,这就是一个“事后状态”,你只能在用户重新打开该标签页时,通过一些蛛丝马迹来推测它曾经被丢弃过。
那么,面对这种不可捕获的事件,有什么办法能在页面被丢弃后,依然能还原用户的操作现场?经验表明,核心在于两个关键环节:一是抓住正确的保存时机,二是写对还原逻辑。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
先看一张图,了解一下整个生命周期的大致流程:

当一个被丢弃的页面重新加载时,浏览器会发起一个全新的导航(navigation),触发 pageshow 事件。此时,事件对象 event.persisted 的值会变成 false。注意:这个值跟页面从 Frozen 状态恢复回来时的 persisted === true 正好相反。也就是说,persisted === false 并不直接代表“被丢弃了”,而是代表“这次不是从 bfcache 缓存恢复的”——是一次全新加载。你需要结合其他信号做交叉判断才靠谱。
比如:
_reloaded=1localStorage 中保存的最后状态时间戳,如果距离当前时间超过 5 分钟,大概率就是被 discard 了——要知道 Frozen 状态通常撑不过 2–3 分钟performance.getEntriesByType('navigation')[0].type,如果值是 'reload' 或 'navigate',这两者都可能对应 discard 后的重建需要警惕的是,performance.navigation.type 这个接口已经废弃了,要用上面那个新 API 代替。
既然 discard 不可逆,那真正能用来保存现场的窗口,只有 discard 发生之前的那几毫秒。可靠的时机只有两个:
event.persisted === true:说明页面将被放入 bfcache,后续可能直接 resume,此时也应把关键状态保存下来在这两个事件中,你可以安全地调用 localStorage.setItem()、写入 indexedDB,或者发送带 keepalive: true 的 navigator.sendBeacon() 来上报快照。不过也得注意:sendBeacon() 在 freeze 事件中不一定能发出去,优先考虑存储类的方案会更可控。
用户回到页面时,第一步就是要判断这次加载属于哪种类型:
pageshow.persisted === false、document.hasFocus() === true、没有残留的 DOM 状态localStorage 或服务端拉取最近一次的快照,手动 restore 表单、滚动位置、选中项等用户状态pageshow.persisted === true最容易忽略的一个细节是:冷启动还原后,务必要清除旧的 localStorage 快照,否则下次再进页面还会误还原成上次的状态。同时,滚动位置的恢复要使用 history.scrollRestoration = 'manual' 配合 scrollTo() 来实现,避免浏览器的默认滚动行为覆盖掉你的手动恢复逻辑。这才是关键所在。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述