**1. 什么是 Web Worker?**
Web Worker 允许在浏览器中创建后台线程,执行耗时的 JavaScript 任务而不阻塞主线程(UI 渲染)。Worker 与主线程通过消息传递机制通信。
**2. 基本使用场景**
- 处理大量数据计算(如复杂数学运算、图像处理)
- 执行耗时的网络请求或文件操作
- 后台监控(如监听传感器数据)
**3. Web Worker 的类型**
- **专用 Worker(Dedicated Worker)**:单个页面创建的 Worker,只能被创建它的页面使用。
- **共享 Worker(Shared Worker)**:多个页面共享的 Worker,可被多个窗口/iframe 访问。
- **Service Worker**:特殊的 Worker,用于拦截网络请求、缓存资源等离线功能。
**4. 专用 Worker(Dedicated Worker)示例**
**主线程代码(main.js)**
javascript
// 创建 Worker 实例,指定 worker 脚本路径
const worker = new Worker('worker.js');
// 向 Worker 发送消息
worker.postMessage('开始计算');
// 监听 Worker 返回的消息
worker.onmessage = function(e) {
console.log('来自 Worker 的消息:', e.data);
};
// 监听 Worker 错误
worker.onerror = function(error) {
console.error('Worker 错误:', error.message);
};
// 终止 Worker
// worker.terminate();
**Worker 线程代码(worker.js)**
javascript
// 监听主线程发送的消息
self.onmessage = function(e) {
console.log('接收到主线程消息:', e.data);
// 执行耗时任务(模拟计算)
const result = heavyCalculation();
// 向主线程返回结果
self.postMessage(result);
};
function heavyCalculation() {
// 模拟耗时操作
let sum = 0;
for (let i = 0; i < 1000000000; i++) {
sum += i;
}
return sum;
}
**5. 共享 Worker(Shared Worker)示例**
**主线程代码**
javascript
// 创建共享 Worker(多个页面可连接同一个 worker)
const sharedWorker = new SharedWorker('shared-worker.js', 'my-shared-worker');
// 向共享 Worker 发送消息
sharedWorker.port.postMessage('Hello from main page');
// 监听共享 Worker 的消息
sharedWorker.port.onmessage = function(e) {
console.log('来自共享 Worker 的消息:', e.data);
};
// 启动端口连接
sharedWorker.port.start();
**共享 Worker 代码(shared-worker.js)**
javascript
// 存储所有连接的端口
const ports = [];
// 监听新连接
self.onconnect = function(e) {
const port = e.ports[0];
ports.push(port);
// 监听端口消息
port.onmessage = function(e) {
// 广播消息给所有连接的端口
ports.forEach(p => p.postMessage(`广播: ${e.data}`));
};
// 发送欢迎消息
port.postMessage('欢迎连接到共享 Worker');
};
**6. Service Worker 基础**
Service Worker 是一种特殊的 Worker,用于拦截网络请求、缓存资源,实现离线应用。
**注册 Service Worker**
javascript
// 在主线程中注册 Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker 注册成功:', registration);
})
.catch(error => {
console.error('Service Worker 注册失败:', error);
});
}
**Service Worker 代码(service-worker.js)**
javascript
// 监听安装事件,缓存静态资源
self.addEventListener('install', event => {
event.waitUntil(
caches.open('my-cache-v1')
.then(cache => cache.addAll([
'/',
'/index.html',
'/style.css',
'/app.js'
]))
);
});
// 监听 fetch 事件,拦截网络请求
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
**7. Worker 的限制与注意事项**
1. **同源限制**:Worker 脚本必须与主线程同源。
2. **无法访问 DOM**:Worker 中不能直接操作 HTML 元素。
3. **通信方式**:通过 `postMessage()` 和 `onmessage` 事件进行消息传递。
4. **数据复制**:消息传递时数据会被复制(结构化克隆),而非共享内存。
5. **全局对象不同**:Worker 中的全局对象是 `self`,而非 `window`。
**8. 兼容性**
主流浏览器均支持 Web Worker,但 IE10 及以下版本不支持。可通过以下代码检测支持性:
javascript
if (typeof Worker !== 'undefined') {
// 支持 Web Worker
} else {
// 不支持,需要降级处理
}
**9. 性能优化建议**
- 避免频繁创建 Worker,可复用已有的 Worker 实例。
- 大数据传递时使用 `Transferable Objects` 提高性能。
- 复杂计算可分割为多个小任务,避免长时间阻塞 Worker 线程。
Web Worker 是现代 Web 应用中处理复杂计算的重要工具,能显著提升用户体验,尤其在处理密集型任务时。