Web Worker 是纯计算单元,需遵循线程隔离、结构化通信、主动生命周期管理及工程化规范。命名用 kebab-case+.worker.js,单职责,禁 DOM/状态,消息含 type 字段与 Transferable,Worker 自行 close,配合 TypeScript 类型定义与 CI 测试。

Web Worker 不是“多开几个脚本”那么简单,它涉及线程隔离、通信边界、资源生命周期和错误兜底。团队协作中若缺乏统一规范,极易出现主线程与 Worker 逻辑耦合、消息结构混乱、内存泄漏、调试困难等问题。核心原则就一条:Worker 是纯计算单元,不碰 DOM、不存状态、只收发结构化消息。
Worker 文件命名与组织规范
保持可发现性与职责单一:
- 文件名统一用 kebab-case,后缀为
.worker.js(如csv-parser.worker.js、image-resize.worker.js),避免与普通工具脚本混淆 - 每个 Worker 文件只实现一个明确任务,禁止“万能 worker”打包所有逻辑
- 复杂任务需拆分子模块时,用
importScripts()加载同域下的.util.js或.shared.js,不支持 ES 模块(除非配置构建工具转译) - Worker 入口必须导出清晰的
onmessage或addEventListener('message'),禁止裸写执行逻辑
主线程与 Worker 的通信协议
消息不是“随便传个对象”,而是有格式、有类型、可追溯的契约:
使用固定的 Next.js/Tailwind/Prisma 技术栈构建并记录独立 SaaS 项目,仅将 FastAPI 用于 Python 工作负载,并遵循严格的架构规范。
- 所有
postMessage()必须发送 plain object,含type字段(如{ type: 'START_PARSE', data: [...] }),禁用原始值(字符串/数字)或函数 - 约定响应结构统一为
{ type: 'PARSE_COMPLETE', payload: result, id?: string },带可选id用于请求-响应匹配(尤其在并发调用时) - 错误统一走
self.postMessage({ type: 'ERROR', code: 'INVALID_INPUT', message: '...' }),不在 Worker 内抛异常(主线程无法捕获) - 大数组/二进制数据优先使用
Transferable(如postMessage(data, [data.buffer])),避免结构化克隆开销
Worker 生命周期与资源管理
它不是“启动就不管”,必须主动控制:
- 主线程创建 Worker 后,应绑定
onerror和onmessage,并设置超时机制(如 30s 未响应则terminate()) - Worker 完成任务后必须调用
self.close(),禁止依赖主线程终止——否则可能残留空转线程 - 禁止在 Worker 中使用
setTimeout/setInterval长期轮询;如需定时行为,由主线程控制节奏并按需唤醒 - Worker 内部不得访问
localStorage、indexedDB(虽部分浏览器允许,但违背无状态原则)、document、window等任何主线程专属 API
团队协作与工程化建议
让 Worker 可测试、可复用、可监控:
- 在 CI 中单独跑 Worker 单元测试:用
node --experimental-worker或 Jest 的testEnvironment: 'node'模拟环境,验证计算逻辑 - 建立
worker-types.d.ts定义消息 Schema(TypeScript),主线程与 Worker 共享接口,保障类型安全 - 上线前检查 Worker 脚本是否被正确打包(Webpack/Vite 需配置
new Worker(new URL('./xxx.worker.js', import.meta.url))动态路径) - 关键业务 Worker 建议加轻量日志:通过
self.postMessage({ type: 'LOG', level: 'info', msg: 'step 2 done' })上报,由主线程聚合分析

















