浏览器工程

Page Lifecycle 与实时应用:冻结、恢复和丢失的定时器

处理 visibilitychange、pagehide、freeze、resume 与系统休眠,区分页面不可见、被冻结和真正离线,恢复时重新核对连接与任务。

工程上最危险的不是完全不可用,而是在理想环境里正常、进入真实网络和真实数据量后悄悄失去边界。 后台标签可能停止定时器和 JavaScript,却不一定立即关闭 WebSocket 或 PeerConnection。应用不能把一次心跳延迟当离线,也不能假设醒来后的旧连接仍然有效。

浏览器能力由版本、权限、页面可见性和设备策略共同决定。实现需要能力探测与可解释降级,不能把某一台开发机上的 API 存在当成产品契约。

工程边界与取舍

实现之前先列出不可违反的不变量,再为性能与体验留出调节参数。参数可以灰度,身份、权限和终态规则不能在运行时随意漂移。

  • 把可见性、执行冻结、网络在线和远端会话拆成独立状态,不压成一个 online。
  • 进入 freeze 前持久化未完成任务与用户停止意图,禁止在事件里做长异步工作。
  • resume 后通过会话版本、心跳和 selected candidate pair 重新对账,再恢复功能。

实时网页要把“代码暂停执行”视为常态。恢复不是继续上一次回调,而是从持久状态和远端事实重新确认当前所有权。

生产环境会怎样出错

失败路径需要与成功路径共享同一套状态模型。只弹一个错误提示却不释放资源、不传播终态,下一次恢复就会继承脏状态。

  • 后台节流让重连计时器集中醒来,数百标签同时冲击信令服务。
  • pagehide 被当永久退出,进入 bfcache 的页面错误撤销信任和任务。
  • 恢复后沿用旧文件发送循环,新循环又启动,导致重复分块和进度倒退。

把测试跑成闭环

测试不能以“最后成功了”结束。还要测量经历了多少次副作用、等待多久、是否泄露内容,以及失败后再次执行能否从干净基线开始。

  1. 让页面后台五分钟、系统休眠和内存冻结分别恢复,检查任务只存在一份。
  2. 用被节流的假时钟批量触发超时,验证重试带抖动且有全局并发上限。
  3. 从 bfcache 返回时确认页面不重复注册事件、WebSocket 或分析监听器。

当实现能够安全降级、重复执行不产生额外副作用、故障指标早于投诉出现时,这项能力才算具备长期维护价值。

把方法变成一次真实连接

打开 uCopy,让两台设备在浏览器里安全连接并开始传输。

开始免费使用