SharedWorker 适用场景
SharedWorker 适合比 BroadcastChannel 和 localStorage 更复杂的应用场景:
- 选择性通信:某些页面需要通信,某些不需要,通过连接 ID 区分
- 共享状态管理:多个 Tab 间共享复杂的状态数据
- 后台执行任务:在独立线程中运行耗时计算,不阻塞 UI
- 全页面广播或定向推送:灵活控制消息的分发范围
每次 Tab 连接到 SharedWorker 时,都会获得一个唯一的连接 ID,开发者可以借此区分不同的页面/标签。
在 Vite/Vue 项目中使用 SharedWorker
创建 Worker 文件
SharedWorker 是一个独立的 JS 文件,通过浏览器的 SharedWorker 接口创建:
// shared-worker.js
const connections = []
self.onconnect = (event) => {
const port = event.ports[0]
const id = connections.length
connections.push(port)
port.start()
port.onmessage = (event) => {
// 收到消息后,可以向所有连接或特定连接转发
connections.forEach((conn, index) => {
if (index !== id) {
conn.postMessage({
from: id,
data: event.data
})
}
})
}
}
javascript
在 Vue 组件中连接 Worker
const worker = new SharedWorker('/shared-worker.js')
// 启动端口
worker.port.start()
// 发送消息
worker.port.postMessage('hello from tab')
// 接收消息
worker.port.onmessage = (event) => {
console.log('收到消息:', event.data)
}
javascript
Vite 中的 Worker 导入
Vite 支持使用 ?sharedworker 后缀直接导入:
import SharedWorker from './shared-worker.js?sharedworker'
const worker = new SharedWorker()
worker.port.start()
javascript
SharedWorker 与其他方案对比
| 特性 | SharedWorker | BroadcastChannel | localStorage |
|---|---|---|---|
| 独立线程 | 是 | 否 | 否 |
| 连接 ID 区分 | 是 | 否 | 否 |
| 复杂状态管理 | 适合 | 一般 | 不适合 |
| 后台任务执行 | 支持 | 不支持 | 不支持 |
| 同源限制 | 是 | 是 | 是 |
| 浏览器支持 | 主流(IE 不支持) | 主流(IE 不支持) | 全部 |
选择建议:如果只是简单的状态同步,BroadcastChannel 或 localStorage 更轻量;如果需要复杂的消息路由、状态共享或后台计算,SharedWorker 是更合适的方案。
↑