加载笔记内容...
加载笔记内容...
JavaScript 的单线程特性源于浏览器的事件循环机制。主线程承担着 UI 渲染、事件处理、网络请求等多项职责,任何阻塞操作都会导致页面卡顿。Web Worker 的诞生正是为了解决这一核心矛盾,其本质是浏览器提供的轻量级线程机制。
类型 | 生命周期 | DOM 访问 | 共享性 |
---|---|---|---|
Dedicated Worker | 与创建者绑定 | ❌ | 私有 |
Shared Worker | 多页面共享 | ❌ | 跨上下文 |
Service Worker | 独立于页面 | ❌ | 代理网络请求 |
(示意图:主线程与 Worker 线程通过消息队列通信)
消息传递使用结构化克隆算法,支持包括 ArrayBuffer、File 等复杂对象的序列化。但需要注意:
1// 错误示例:函数无法被克隆
2worker.postMessage({ method: () => {} }); // 抛出 DataCloneError
3
4// 正确使用 Transferables
5const buffer = new ArrayBuffer(1024);
6worker.postMessage(buffer, [buffer]); // 转移所有权
ES Module Worker 改变了传统脚本加载方式:
1// 主线程
2const worker = new Worker('./image-processor.js', {
3 type: 'module',
4 credentials: 'same-origin'
5});
6
7// Worker 内部
8import { createFilter } from '@wasm-filters/core';
9import wasm from './filter.wasm?module';
worker-loader 的进阶配置示例:
1// webpack.config.js
2{
3 test: /\.worker\.ts$/,
4 use: [
5 {
6 loader: 'worker-loader',
7 options: {
8 filename: '[name].[contenthash].js',
9 inline: 'fallback' // 小于 4KB 内联为 Blob URL
10 }
11 },
12 'babel-loader'
13 ]
14}
1// 利用 OffscreenCanvas
2const offscreen = canvas.transferControlToOffscreen();
3worker.postMessage({ canvas: offscreen }, [offscreen]);
4
5// Worker 端
6onmessage = (e) => {
7 const canvas = e.data.canvas;
8 const ctx = canvas.getContext('2d');
9 // 执行 WebGL 渲染...
10};
1// 使用 TensorFlow.js 后端
2import * as tf from '@tensorflow/tfjs';
3tf.setBackend('wasm');
4
5self.onmessage = async ({ data }) => {
6 const model = await tf.loadGraphModel(MODEL_URL);
7 const prediction = model.predict(tf.tensor(data));
8 self.postMessage(prediction.arraySync());
9};
1// 使用 FinalizationRegistry 监控对象生命周期
2const registry = new FinalizationRegistry((heldValue) => {
3 console.log(`对象 ${heldValue} 被 GC 回收`);
4});
5
6registry.register(largeObject, "LargeData");
1// worker.js
2debugger; // 传统断点
3console.timeStamp('Worker 启动'); // 性能标记
1// 并行计算示例
2const threads = navigator.hardwareConcurrency;
3const workers = Array.from({ length: threads }, () => new Worker('wasm-worker.js'));
4
5Promise.all(workers.map(worker => {
6 return new Promise(resolve => {
7 worker.onmessage = e => resolve(e.data);
8 worker.postMessage(taskSegment);
9 });
10}));
任务类型 | 适合 Worker 化 | 注意事项 |
---|---|---|
图像/视频处理 | ✅ | 注意内存传输开销 |
复杂算法计算 | ✅ | 避免过度拆分任务粒度 |
实时数据分析 | ✅ | 控制消息频率 |
DOM 操作 | ❌ | 违反线程安全原则 |
1// 心跳检测机制
2const heartbeat = setInterval(() => {
3 worker.postMessage({ type: 'ping' });
4}, 5000);
5
6worker.onmessage = (e) => {
7 if (e.data === 'pong') return;
8 // ...处理正常消息
9};
10
11// 异常处理
12worker.onerror = (err) => {
13 console.error('Worker 崩溃:', err);
14 restartWorker();
15};
虽然 Worker 隔离了执行环境,但共享资源(如 IndexedDB)仍可能引发竞争条件。推荐使用:
当遇到以下场景时,考虑其他方案可能更优:
Web Worker 技术历经多年发展,已从简单的计算卸载工具演变为现代 Web 应用的核心架构组件。随着 WebAssembly 线程提案的推进和浏览器新特性的不断涌现,开发者需要持续关注以下方向:
建议定期查阅 Web Workers W3C 规范 和 Chrome 平台状态 获取最新动态,在工程实践中保持技术敏感度与架构前瞻性。