Web Workers 是 JavaScript 唯一官方并行机制,需独立 JS 文件加载、仅通过 postMessage 通信(结构化克隆)、无 DOM 访问权限、适合 CPU 密集型长任务,不适合轻量或高频操作。

JavaScript 本身是单线程的,Web Workers 是唯一能让 JS 真正并行执行计算任务的官方机制——但它不是“开个线程随便跑”,而是有明确边界和通信约束。
Web Worker 必须从独立 JS 文件加载,不能内联
你不能用 new Worker("function() { ... }") 或字符串构造 Worker。浏览器强制要求 Worker 脚本必须是单独的、可跨域访问的 .js 文件(或通过 Blob URL 动态生成)。
- ✅ 正确:
const worker = new Worker("./math-worker.js"); - ❌ 错误:
new Worker("postMessage(42)");(会抛出DOMException: Failed to construct 'Worker') - ⚠️ 注意:本地文件协议(
file://)下多数浏览器会直接拒绝加载 Worker,需走http://或https://(包括localhost)
主线程与 Worker 只能通过 postMessage 通信,且数据被结构化克隆
postMessage() 是唯一通信方式,传参不是引用传递,而是经过 structuredClone()(或旧版结构化克隆算法)序列化 —— 所以 function、undefined、Symbol、Promise、DOM 节点 都无法传递。
- ✅ 可传:
Number、String、Array、Object(纯 JSON 可序列化的)、TypedArray、Map/Set(现代环境) - ⚠️ 大数组建议用
transferable:比如worker.postMessage(arr.buffer, [arr.buffer]),避免拷贝,直接移交所有权 - ❌ 不要试图在 Worker 里操作
document或调用alert()—— 它没有 DOM 和 window 上下文
Worker 内部不能访问 this、window、document,但有 self 和专用 API
Worker 全局作用域是 self(等价于 globalThis),不是 window。它支持 fetch、setTimeout、WebAssembly、IndexedDB,但不支持 localStorage、console.log(部分浏览器支持,但行为不一致,建议用 self.postMessage({ type: "log", msg }) 回传调试)。
立即学习“Java免费学习笔记(深入)”;
- ✅ 可用:
self.onmessage = e => { ... }、self.close()、importScripts("lib.js")(同步加载依赖) - ⚠️
importScripts()是阻塞的,别加载大文件;现代项目更推荐用 ES Module Worker:new Worker("./worker.js", { type: "module" }),然后用import语句 - ❌ 别写
console.log依赖日志定位问题 —— 它可能不输出,或输出到不可见位置
频繁通信或小任务反而拖慢性能,适合 CPU 密集型长时计算
Worker 的启动、消息序列化/反序列化、事件循环调度都有开销。如果任务本身只耗几毫秒,或者需要高频来回传数据(如每帧计算一次),用 Worker 可能比直接在主线程跑还慢。
- ✅ 合适场景:图像处理(Canvas 像素遍历)、加密解密、大数组排序/搜索、解析大型 JSON/XML、路径规划、物理模拟
- ⚠️ 避免场景:简单加减、调用一次 fetch、渲染前做轻量格式转换
- ? 小技巧:把多个小计算合并成一批传给 Worker,减少通信次数;用
Transferable加速大数据传输
真正难的不是怎么写 Worker,而是判断「这个任务值不值得扔进去」——很多性能问题其实出在算法或数据结构上,而不是线程数不够。











