浏览器支持
Dedicated Worker / SharedWorker: 几乎所有浏览器
Service Worker: Chrome 40+ · Firefox 44+ · Safari 11.1+ · Edge 79+
Worklet: Chrome 49+ / Safari 不完整支持
概述
很多人把 Service Worker 和 Dedicated/Shared Worker 混为一谈,觉得都是"后台线程"。其实它们解决的问题完全不同:
- Dedicated / Shared Worker:帮主线程分担计算量,用
postMessage通信 - Service Worker:充当浏览器和网络之间的代理,用事件驱动的 fetch 响应来拦截/缓存请求
Service Worker 不是 Worker 线程,它是运行在浏览器注册域下的一个独立的生命周期,更像一个在后台运行的脚本,可以拦截网络请求、推送通知、管理缓存。
一张表说清楚区别
| 特性 | Dedicated Worker | Shared Worker | Service Worker |
|---|---|---|---|
| 创建方式 | new Worker(url) | new SharedWorker(url, name) | navigator.serviceWorker.register(url) |
| 线程模型 | 独立线程 | 独立线程(可跨 Tab 共享) | 独立线程(事件驱动) |
| DOM 访问 | 无 | 无 | 无 |
| 网络请求 | fetch | fetch | fetch + 拦截 fetch |
| 缓存管理 | 无 | 无 | Cache API / Cache Storage |
| 推送通知 | 无 | 无 | Push API / Notification API |
| 生命周期 | terminate() / close() | close() | 安装 → 激活 → 废弃 |
| 离线能力 | 无 | 无 | 可实现离线应用 |
| 作用域 | 自身 | 同源 | 有路径作用域 |
| 通信方式 | postMessage | postMessage(经 port) | 事件(fetch、push、message) |
| 用途 | 计算密集任务 | 跨 Tab 共享状态 | 网络代理、PWA 离线、推送 |
什么时候用哪个?
是否需要拦截网络请求?
├── 否 → 是否需要跨 Tab 共享状态?
│ ├── 否 → Dedicated Worker
│ └── 是 → Shared Worker(或 BroadcastChannel)
└── 是 → Service Worker(PWA / 离线应用 / 推送)注意事项
- HTTPS 强制:Service Worker 必须跑在 HTTPS 下(localhost 除外)
- 作用域限制:Service Worker 的
scope决定它能拦截哪些路径的请求;子路径会被覆盖,父路径不行 - Service Worker 可以被浏览器同时存在多个版本:旧版本会在所有页面都不再使用后被回收
- Service Worker 里的
self是ServiceWorkerGlobalScope:它有caches、fetch、clients等 Dedicated Worker 里没有的 API - Service Worker 退出后事件消失:它只在有事件触发时才活着;空闲时会被浏览器挂起,这是设计意图,不是 bug