浏览器工程

bfcache 遇到 WebSocket 与 WebRTC:返回页面时别复制一套连接

解释 pageshow.persisted、pagehide 与 bfcache 资格,设计连接暂停、事件注销、返回后的状态核对和不适合缓存时的明确退出。

好的实现不会依赖用户反复刷新碰运气,而会让每个阶段有明确输入、输出、超时和终态。 后退缓存保存整个页面内存快照,返回时不会重新执行普通初始化。网络对象可能已失效,旧事件监听却仍存在;如果再跑一次 mounted 初始化,就会产生双连接。

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

先定义系统契约

这项能力横跨客户端、网络与服务端,局部最优很容易制造全局故障。工程决策需要同时约束两端行为、持久化事实和运维预算。

  • pagehide 时记录页面纪元并暂停任务,persisted 为真时不删除长期信任。
  • pageshow 返回后先检查旧对象状态,再决定复用、ICE restart 或完整重建。
  • 所有全局监听和通道回调绑定页面纪元,旧纪元事件不能修改当前 store。

支持 bfcache 的关键是页面纪元与幂等初始化。能恢复就对账恢复,无法恢复就明确结束,不要半复用旧对象再叠加新对象。

哪些情况会破坏契约

生产问题往往发生在两个正确动作同时到达时。需要逐条检查迟到消息、重复执行、资源耗尽和版本交叉,而不是只补当前堆栈显示的那一行。

  • beforeunload 监听长期存在让页面失去 bfcache 资格并拖慢导航。
  • 返回后无条件 connect,而旧 WebSocket 其实仍在线,通知和消息成双。
  • 为了支持缓存不发送离开状态,远端长期认为屏幕观看者仍存在。

如何逐条验证契约

发布闸门应包含确定性回归、随机时序探索和真实浏览器组合。发现一次失败后保存 seed 与状态轨迹,让它永久成为可重放用例。

  1. 前进后退一百次,断言同一设备仅有一个信令连接和一个事件处理器。
  2. 分别让旧连接在缓存期间保持、失败和被服务端替换,验证返回决策。
  3. 屏幕观看和文件接收中进入 bfcache,确认远端状态在宽限期后准确收敛。

最终交付标准应当是:正常路径足够快,异常路径能够收敛,用户意图不会被自动恢复覆盖,运维人员也能从有限而安全的证据定位问题。

把方法变成一次真实连接

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

开始免费使用