Web Workers 是浏览器提供的独立线程机制,用于将耗时 JS 任务移出主线程以避免阻塞 UI;其本质是无 DOM、受限的 JS 环境,与主线程隔离,仅支持通过 postMessage 传递可序列化数据。

Web Workers 是浏览器提供的独立线程机制,能真正把耗时 JS 任务移出主线程,避免卡死 UI —— 但不是所有代码都能直接扔进去跑。
Web Worker 的本质:一个受限的、无 DOM 的 JS 环境
它和主线程完全隔离,不能访问 window、document、alert,也不能操作 DOM。你传给它的只能是纯数据(或可序列化的对象),它返回的也必须是可序列化的结果。
- Worker 脚本必须是独立文件(如
worker.js),不能是内联字符串或箭头函数 - 主线程用
new Worker('worker.js')启动,用postMessage()发送数据,用onmessage接收 - Worker 内部用
self.onmessage和self.postMessage()通信,不能用this或window - 注意跨域限制:Worker 脚本必须同源,或通过
Content-Security-Policy显式允许
怎样把计算密集型任务塞进 Worker:以大数组排序为例
比如主线程有 100 万个数字要排序,直接调用 arr.sort() 会阻塞页面几百毫秒。这时可以把排序逻辑抽到 Worker 中:
/* worker.js */
self.onmessage = function(e) {
const arr = e.data;
const sorted = arr.sort((a, b) => a - b);
self.postMessage(sorted);
};主线程调用:
立即学习“Java免费学习笔记(深入)”;
const worker = new Worker('worker.js');
worker.postMessage([3, 1, 4, 1, 5, 9, 2, 6]);
worker.onmessage = function(e) {
console.log('排序完成:', e.data); // [1, 1, 2, 3, 4, 5, 6, 9]
};- 注意:
postMessage()默认使用结构化克隆算法,大数组会拷贝,可能慢;可用Transferable(如postMessage(data, [data.buffer]))零拷贝传递ArrayBuffer - 不要在 Worker 里做
fetch后立刻解析 JSON 大文本 —— 解析本身也耗 CPU,应一并交给 Worker 处理 - 频繁通信(如每 10ms 传一次)反而比不拆线程更慢,适合“启动 → 计算 → 返回”类任务
常见报错和绕不过去的坑
遇到 SecurityError: Failed to construct 'Worker'?多半是本地文件协议(file://)下加载 Worker —— 浏览器禁止,必须走 HTTP(S) 服务。
-
ReferenceError: window is not defined:Worker 里写了window.location或localStorage,换用self.location(仅部分属性可用)或改用postMessage让主线程代劳 -
TypeError: Cannot read property 'addEventListener' of undefined:试图在 Worker 里绑事件监听器,删掉,它没有document - 调试困难?Chrome DevTools 的
Sources → Threads标签页可设断点、看 Worker 控制台输出,但无法 inspect 变量作用域链 - Worker 不会自动销毁,记得在不需要时调用
worker.terminate(),否则内存泄漏
真正难的从来不是“怎么启一个 Worker”,而是判断哪些逻辑该拆、拆多细、数据怎么切分又不增加通信开销——尤其是涉及状态共享或中间结果复用时,线程边界比想象中更硬。











