Service Worker vs Web Worker 对比
Service Worker 和 Web Worker 都是运行在浏览器后台的 JavaScript 线程,但它们的设计目标和应用场景完全不同。
核心区别对比表
| 特性 | Service Worker | Web Worker |
|---|---|---|
| 主要用途 | 网络代理、离线缓存、推送通知 | 执行复杂计算、避免阻塞主线程 |
| 生命周期 | 独立于页面,可长期运行 | 与页面绑定,页面关闭即终止 |
| DOM 访问 | ❌ 无法访问 | ❌ 无法访问 |
| 网络拦截 | ✅ 可以拦截所有网络请求 | ❌ 无法拦截 |
| 事件驱动 | ✅ 基于事件(fetch, push, sync) | ✅ 基于消息传递 |
| 安装方式 | 需要注册,有独立生命周期 | 直接实例化 Worker 对象 |
| 持久化 | ✅ 浏览器可自动重启 | ❌ 页面关闭即销毁 |
| 通信方式 | postMessage + clients API | postMessage |
Service Worker 特点
1. 网络代理能力
javascript// Service Worker 可以拦截所有网络请求 self.addEventListener('fetch', event => { event.respondWith( caches.match(event.request).then(response => { return response || fetch(event.request); }) ); });
2. 独立于页面的生命周期
- 安装后持续运行,即使所有页面关闭
- 浏览器可自动重启处理事件
- 适合后台任务(推送通知、后台同步)
3. 渐进式 Web 应用核心
javascript// 推送通知 self.addEventListener('push', event => { event.waitUntil( self.registration.showNotification('新消息', { body: event.data.text() }) ); }); // 后台同步 self.addEventListener('sync', event => { if (event.tag === 'sync-data') { event.waitUntil(syncData()); } });
Web Worker 特点
1. 计算密集型任务
javascript// main.js const worker = new Worker('worker.js'); worker.postMessage({ numbers: [1, 2, 3, 4, 5] }); worker.onmessage = event => { console.log('Result:', event.data); }; // worker.js self.onmessage = event => { const { numbers } = event.data; const result = numbers.reduce((a, b) => a + b, 0); self.postMessage(result); };
2. 页面级生命周期
- 创建它的页面关闭时自动终止
- 适合处理一次性计算任务
- 无法执行后台持续任务
3. 多种类型
javascript// 专用 Worker(Dedicated Worker) const worker = new Worker('worker.js'); // 共享 Worker(Shared Worker)- 多页面共享 const sharedWorker = new SharedWorker('shared-worker.js'); // Service Worker(特殊类型) navigator.serviceWorker.register('sw.js');
使用场景对比
Service Worker 适用场景
- 离线应用:缓存资源,提供离线访问
- 网络优化:智能缓存策略,减少网络请求
- 推送通知:接收服务器推送的消息
- 后台同步:网络恢复后自动同步数据
- PWA 功能:添加到主屏幕、应用壳架构
Web Worker 适用场景
- 大数据处理:图片处理、视频编解码
- 复杂计算:数学运算、数据分析
- 实时数据处理:WebSocket 数据解析
- 文件处理:大文件读取、压缩
- 避免 UI 阻塞:耗时操作不卡顿界面
代码示例对比
Service Worker 示例
javascript// 注册 navigator.serviceWorker.register('/sw.js'); // sw.js - 拦截请求 self.addEventListener('fetch', event => { event.respondWith(caches.match(event.request)); }); // 与主线程通信(通过 clients) self.clients.matchAll().then(clients => { clients.forEach(client => client.postMessage('update')); });
Web Worker 示例
javascript// 创建 Worker const worker = new Worker('/worker.js'); // 发送消息 worker.postMessage({ action: 'calculate', data: [1, 2, 3] }); // 接收消息 worker.onmessage = event => { console.log('Result:', event.data); }; // worker.js self.onmessage = event => { const result = performCalculation(event.data); self.postMessage(result); };
总结
- Service Worker:网络代理专家,负责离线体验、后台任务
- Web Worker:计算性能专家,负责耗时运算、避免阻塞
- 两者关系:互补而非替代,可在 PWA 中同时使用