sharedworker 全局变量天然共享,需通过 messageport 会话隔离、不可变状态封装、service worker 协同及端口生命周期管理实现逻辑隔离。

SharedWorker 本身不支持全局变量的“自动隔离”,所有连接它的页面共享同一个执行上下文,因此全局变量天然是共享的——这不是“污染”,而是设计特性。关键在于开发者如何主动管理状态,避免意外覆盖或竞态。核心策略不是阻止共享,而是控制共享的方式。
用 MessagePort 实现逻辑隔离
SharedWorker 内部不应直接暴露全局可变对象(如 window.sharedState),而应将每个端口(MessagePort)视为独立会话入口:
- 为每个 connect 事件创建唯一 session ID,并在内部 Map 中维护该端口专属的状态快照
- 所有读写操作都绑定到 port 对象或其关联的 session ID,而非全局变量
- 示例:接收消息时先通过 event.ports[0] 获取当前端口,再查表获取对应数据上下文
禁止直接操作 globalThis / self 上的可变属性
SharedWorker 的 self 就是全局作用域,任何 self.cache = {} 或 let config = {...} 都会被所有页面共用:
- 把配置类数据设为 const 或 Object.freeze(),杜绝运行时修改
- 状态类数据必须封装在闭包或模块作用域内,仅通过受控接口访问(如 getState(port)、updateState(port, data))
- 避免使用 var/let 声明跨端口通用状态变量;改用函数式更新 + 不可变结构(如用 structuredClone 返回新副本)
利用 Service Worker 协同做资源级隔离
SharedWorker 不适合承载高耦合状态,但可与 Service Worker 配合分层:
- SharedWorker 专注轻量通信中转(如广播事件、统一鉴权校验、ID 分配)
- 敏感或页面专属数据(如用户偏好、临时缓存)交由 Service Worker 管理,按 scope 或 client ID 隔离
- SharedWorker 仅向 Service Worker 发送指令(如 sync: user-preferences),由后者完成实际读写
监听 close 并及时清理端口关联状态
SharedWorker 不会自动感知页面关闭,需手动处理连接生命周期:
- 在 connect 回调中保存 port 引用,并绑定 port.onmessage 和 port.onclose
- onclose 触发时,从 session Map 中删除该 port 对应的所有状态(包括定时器、缓存引用等)
- 定期检查未响应端口(如超时 5 秒无心跳消息),主动 port.close() 并清理,防止内存泄漏
SharedWorker 的“隔离”本质是逻辑隔离,不是环境隔离。只要不把状态平铺在全局,而是绑定到通信通道、封装访问路径、明确生命周期,就能安全复用同一实例服务多个页面。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











