pagehide是更稳的移动端异步退出存盘触发事件,因其在页面被系统回收、后台切换或PWA冻结时仍可靠触发,且event.persisted===false时明确标识页面将销毁,是执行同步存盘(如localStorage.setItem)的最后确定性窗口。

用 window.onpagehide 实现移动端异步退出存盘,核心在于它比 beforeunload 和 unload 更可靠——前者在页面被系统回收、后台切换、PWA 被冻结等场景下仍能触发,而后者在 iOS Safari、Android Chrome 的多任务管理中常被跳过或截断。
为什么 pagehide 是更稳的选择
移动端浏览器(尤其 iOS)为节省资源,会在用户切出标签页或进入多任务视图时快速冻结页面。此时:
-
beforeunload不触发(Safari 完全禁用,Chrome 限制调用) -
unload极大概率不执行(无事件循环时间,无法发起网络请求) -
pagehide保证触发,且event.persisted === false时明确表示页面将被销毁(非缓存恢复),正是存盘的最后窗口
关键操作必须同步完成
即使在 pagehide 中,也不能依赖异步 API(如 fetch、IndexedDB 写入)完成存盘——因为页面可能在 Promise resolve 前就被终止。正确做法是:
- 仅使用同步存储机制:如
localStorage.setItem(快、阻塞、100% 可靠) - 若需结构化/大容量数据,提前建立
SharedArrayBuffer或内存映射缓存,在pagehide中仅做标记+写入轻量元数据 - 避免任何 await、setTimeout、requestIdleCallback 等延迟逻辑
配合 visibilitychange 提前降级处理
单靠 pagehide 不够,应叠加 visibilitychange 主动响应:
- 监听
document.visibilityState === 'hidden',立即暂停轮询、动画、长连接心跳 - 触发一次轻量级本地快照(如记录当前编辑光标位置、表单草稿哈希)
- 为
pagehide阶段减少待存数据量,缩短其执行耗时,提升成功率
兜底策略:离开前主动触发保存
对关键业务(如文档编辑、表单填写),不要只等系统事件:
- 用户点击“返回”“提交”“关闭”按钮时,同步执行存盘并加 loading 锁定 UI
- 监听页面路由变化(如 React Router 的
useBlocker或原生popstate),拦截非预期跳转并强制保存 - 在
pagehide中只作为最终保险,不承担主存盘逻辑
本质上,这不是换一个事件就能解决的问题,而是把“存盘”拆成可中断的预存 + 必成功的终存两层。pagehide 是那道不可绕过的终门,但门后只能放得下确定性操作。

















