web worker 的核心在于理解通信机制、作用域边界和生命周期管理:消息传递本质是结构化克隆而非共享内存,worker 与主线程完全隔离、无 dom 访问权,且必须显式终止以避免资源泄漏。

Web Worker 的核心不是记住 API,而是理解“为什么必须这样设计”。掌握它不靠死记 new Worker() 和 postMessage,而在于吃透通信机制、作用域边界和资源生命周期这三点。
搞懂通信不是传数据,是跨线程“换内存”
主线程和 Worker 之间没有共享变量,postMessage 不是发送引用,而是序列化后复制一份再传输。这意味着:
- 传递大数组或对象时,默认会深拷贝,性能差;用
transferable(如 ArrayBuffer)可零拷贝移交控制权,但移交后原线程不能再访问该内存 - 不能传函数、DOM 节点、Date 对象等不可序列化类型;Date 可转成时间戳再传
- 消息体本质是结构化克隆(structured clone),不是 JSON —— 支持 Map、Set、TypedArray,但不支持循环引用
认清 Worker 的“独立王国”边界
Worker 没有 window、document、localStorage,但它有自己的一套可用能力:
- 能用
self(不是 window)、fetch、XMLHttpRequest、IndexedDB、setTimeout等 - 不能操作 DOM,也不能监听 click、scroll 等 UI 事件——这不是限制,而是多线程安全的必然要求
- 可通过
importScripts('a.js', 'b.js')加载依赖脚本,但不支持 ES 模块语法(除非用new Worker(url, { type: 'module' }))
生命周期管理不是可选项,是必修课
Worker 创建后一直存活,直到被显式终止或页面卸载。不清理会持续占用内存和 CPU:
- 主线程调用
worker.terminate()立即销毁,无回调 - Worker 内部调用
self.close()主动退出,适合任务完成后的优雅收尾 - 不要依赖 GC 自动回收;长期运行的 Worker 应配合 abortController 或信号机制做超时控制
- 频繁创建/销毁 Worker 开销大,可考虑 Worker Pool 模式复用实例
调试和错误处理要落到具体位置
Worker 报错不会出现在主线程控制台,容易漏掉:
- 主线程监听
worker.onerror,捕获初始化失败或脚本语法错误 - Worker 内部需加
try/catch,把异常结果通过self.postMessage({ error: msg })传回,而不是依赖 onerror(部分错误不触发) - Chrome DevTools 的 “Application → Service Workers” 标签下可查看所有 Worker,点击可打开专用调试面板,
console.log输出会显示在那里 - 本地双击 HTML 打开会因跨域报错,必须用本地服务器(如 VS Code Live Server)启动











