web worker用于将纯计算任务移至后台线程以避免主线程卡顿。适合大数组排序、图像处理、加密解密等不操作dom的任务;不适合涉及dom、fetch后更新界面等操作。需通过http服务运行,构建工具中应使用new worker(new url('./worker.js', import.meta.url), {type: 'module'}),通信时优先传递可转移对象以避免内存复制,并务必添加onerror监听与try/catch错误处理。

用 Web Worker 减轻主线程,核心就一条:把纯计算、不碰 DOM 的重活挪到后台线程跑,让主线程专心管界面和交互。它不提速计算本身,但能彻底避免页面卡顿。
哪些任务适合交给 Web Worker
判断标准很简单:任务是否只做计算、不读写 DOM、不依赖 window 或 document。
- 适合的:大数组排序、图像像素处理(如灰度/模糊)、JSON 解析与结构转换、AES 加密解密、素数筛、斐波那契递归计算
- 不适合的:调用 fetch 后直接改按钮文字、给某个 div 添加 class、读取 localStorage 并立刻更新页面 —— 这些必须在主线程完成,Worker 做不了
正确创建和加载 Worker 实例
路径和环境错一点,Worker 就起不来。本地双击 HTML 文件会直接报错,必须走 HTTP 协议。
- 开发时推荐用 npx http-server 或 VS Code 的 Live Server 插件启动服务
- Vite / Webpack 等现代构建工具中,别写 new Worker('./worker.js'),要用:
new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }) - 需要动态生成逻辑(比如按参数选不同算法),可用 Blob 构造:
new Worker(URL.createObjectURL(new Blob([code], {type: 'application/javascript'})))
高效通信与数据传输
消息传递有开销,传得不对反而拖慢整体性能。
- 只传结构化克隆支持的类型:普通对象、数组、ArrayBuffer、TypedArray、Date、RegExp;函数、undefined、DOM 节点、ImageData 本身都不行
- 传大图像数据?别直接 postMessage(imgData)。应提取 imgData.data.buffer,再用 postMessage(data, [data.buffer]) 移交所有权,避免内存复制翻倍
- 主线程监听必须写全:worker.onmessage = e => { /* 处理 e.data */ };
Worker 内必须用 self.onmessage 或 self.addEventListener('message', ...),self 是唯一全局对象
错误处理与生命周期管理
Worker 出错不会打断主线程,但也不会自动报错 —— 不监听就静默失败。
- 主线程务必加:worker.onerror = e => console.error('Worker failed:', e.message);
- Worker 内部也建议包 try/catch,尤其在解析或计算前校验输入数据,防止无效参数导致中断
- 任务完成后可主动调用 self.close() 释放资源,避免长期空转占用内存











