web worker 不提升计算速度,仅将 cpu 密集任务移出主线程;需 http 服务运行、正确路径解析(如 new url)、显式通信监听、结构化克隆传参、transfer 内存优化、错误捕获及避免 dom/过多 console。

Web Worker 本身不加速计算,只把 CPU 密集型任务移出主线程——只要没把真卡点塞进去,或者通信/加载写错,页面照样卡。
new Worker() 加载失败的常见原因
直接写 new Worker('worker.js') 在本地双击打开或 Vite 开发环境下大概率报 SecurityError: Failed to construct 'Worker' 或 net::ERR_FILE_NOT_FOUND。
- file:// 协议下完全不可用,必须起 HTTP 服务(比如
npx http-server或 VS Code Live Server) - Vite / Webpack 等 ESM 环境必须用
new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }),否则路径解析失败 - 避免相对路径如
./worker.js,构建后可能被重命名或移动;用new URL()显式定位最稳 - 动态逻辑可用 Blob:const blob = new Blob(['self.onmessage = e => self.postMessage(e.data * 2);'], {type: 'application/javascript'}); const worker = new Worker(URL.createObjectURL(blob))
主线程与 Worker 通信必须显式监听
不写 onmessage 就等于没接线——消息发出去了,但没人收,结果就是“没反应”。
- 主线程侧:必须设
worker.onmessage = e => { /* 处理 e.data */ },不能只依赖闭包或全局变量 - Worker 侧:必须用
self.onmessage = e => { /* 处理 e.data */ }或self.addEventListener('message', ...),self是唯一全局对象,没有window - 传参只能是结构化克隆支持的类型:普通对象、数组、字符串、Date、RegExp(注意:lastIndex 不会同步)、ArrayBuffer 等;函数、
undefined、Symbol、DOM 节点全丢失 - 错误必须单独捕获:
worker.onerror = e => console.error(e.message),否则静默失败
大对象传输不加 transfer 就等于内存翻倍
传一个 10MB 的 Uint8Array,如果不移交所有权,主线程和 Worker 各持一份副本,低端机直接 OOM。
- 必须用
postMessage(data, [data.buffer]),第二个参数只接受ArrayBuffer、TypedArray、MessagePort等可转移对象 - 移交后,主线程的
data.buffer变成byteLength: 0,再读会静默失败(不是报错) - 别传
ImageData对象本身——它不可 transferable,会抛DataCloneError;提取data.data.buffer单独移交 - 对象字段尽量扁平:避免
{meta: {id: 1}, payload: new Uint8Array()},把payload.buffer单独 transfer,元数据走普通克隆
Worker 内部也要防“自己假死”
哪怕在 Worker 里,一个没中断检查的 for (let i = 0; i 也会阻塞其自身消息循环——主线程发来的取消指令收不到,<code>setTimeout 不触发,Chrome DevTools 标红 “Unresponsive Worker”。
- 必须分片:比如处理长文本时按 2000 字符/段切开,每段处理完用
setTimeout(processNextChunk, 0)让出控制权 - 每块开头检查中断信号:
if (shouldCancel) { self.postMessage({ type: 'cancelled' }); return; } - 不要用
requestIdleCallback:它在 Worker 中不可用;Promise.resolve().then()更轻量 - 超时控制建议加一层:Worker 内用
setTimeout(() => self.postMessage({ type: 'timeout' }), 5000),主线程收到后调worker.terminate()
最容易被忽略的是:Worker 脚本里写了 document.querySelector 或 console.log 过多——前者直接报错崩掉,后者在某些浏览器中会拖慢消息吞吐;纯计算逻辑里,连 console 都该节制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











