sharedworker必须用独立js文件且同源加载,页面端需调用port.start()才能通信;worker内共享state无原子性,高并发易丢数据;safari 16.4+才支持,http环境静默禁用。

SharedWorker 必须用独立 JS 文件,不能内联
直接写 new SharedWorker('data:application/javascript,console.log(1)') 会失败,浏览器只接受真实 URL 脚本。你得把 Worker 逻辑单独存为 shared-state-worker.js,并确保它能被同源页面正常加载(比如放在根目录或 /workers/ 下)。开发时若用 Vite 或 Webpack,注意配置 public 目录或 worker 插件输出路径;否则 404 是第一个拦路虎。
页面端必须调用 port.start() 才能收发消息
很多人写了 const worker = new SharedWorker('shared-state-worker.js') 就以为通了,结果 onmessage 一直不触发——因为默认情况下端口处于“暂停”状态。必须显式启动:
const port = worker.port; port.onmessage = (e) => console.log(e.data); port.start(); // ⚠️ 缺少这行,消息就卡住
如果你用了 addEventListener('message', ...),也得在绑定后调 port.start();否则即使 Worker 发了消息,页面也收不到。
Worker 内部 state 共享但无锁,高并发写入会丢数据
SharedWorker 的全局变量(如 let state = { count: 0 })确实是所有端口共用的,但 JavaScript 没有原子操作。两个标签页同时执行 state.count++,最终可能只加了 1 次。常见错误包括:
- 用
++、+=等非原子操作更新数字或对象字段 - 把
self.clients.matchAll()结果缓存后反复用,而没考虑期间有端口已断开 - 广播消息时未过滤已关闭的
port,导致port.postMessage()报错
简单场景可用标记位控制(如 if (!updating) { updating = true; /* 修改 state */; updating = false; }),更稳的做法是把变更封装成队列 + 单次轮询处理。
Safari 16.4+ 才支持,旧版本需降级 fallback
Chrome、Edge、Firefox 都支持多年,但 Safari 直到 iOS 16.4 / macOS 13.3(2023 年初)才加入 SharedWorker。现在(2026 年)虽已覆盖主流用户,但仍有部分企业内网或教育设备跑着旧系统。检测方式很简单:
if (typeof SharedWorker === 'undefined') {
// 退到 BroadcastChannel + localStorage 时间戳选举
}
别只靠 navigator.userAgent 判断;Safari 伪装 UA 的情况不少。真正关键的是运行时能力检测,而且 fallback 逻辑得和主流程对齐——比如 SharedWorker 里发 { type: 'SET', key: 'authToken', value: 'xxx' },fallback 里也得监听 storage 变更并 emit 同样结构的消息,否则业务层要写两套处理分支。
最易被忽略的是 HTTPS 限制:本地开发用 localhost 没问题,但一旦部署到 HTTP 域名,SharedWorker 会被静默禁用,连 onerror 都不触发。上线前务必确认协议和证书有效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











