Web Worker是浏览器提供的后台线程,用于执行耗时计算而不阻塞主线程;它通过new Worker()创建、postMessage通信、self.onmessage接收,不共享内存且无法操作DOM,仅支持结构化克隆的数据传递。

直接上手学 Web Worker,不用绕弯子。核心就三件事:创建它、传数据、收结果。只要搞清主线程和 Worker 线程各管什么、怎么说话、哪些事不能做,两天就能写出可用的 Worker 代码。
先明白它到底解决什么问题
JavaScript 是单线程的,所有逻辑、渲染、事件、定时器全挤在一条线上跑。一旦有个计算要跑 500ms,页面就卡住——滚动卡、按钮点不动、动画停摆。这不是代码写得差,是浏览器机制决定的。
Web Worker 就是给 JS “开小灶”:新开一个后台线程,专门干耗 CPU 的活(比如解析大 JSON、加密解密、遍历百万数组),主线程继续响应用户、更新界面,互不耽误。
注意:Worker 不是“让 JS 变快”,而是“不让 JS 卡住”。它不提速单个任务,但能保住交互流畅性。
创建 Worker 的正确姿势
必须用一个独立的 .js 文件启动,不能写内联脚本或字符串。路径要同源,且不能是 file:// 协议(本地双击 HTML 会失败,得用本地服务如 npx serve 或 Vite 启动)。
- ✅ 推荐写法(Vite / 模块化项目):
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); - ✅ 传统写法(同目录下有 worker.js):
const worker = new Worker('./worker.js'); - ❌ 错误写法:
new Worker('data:text/javascript,console.log(1)')(兼容性差)new Worker('https://cdn.com/worker.js')(跨域报错)
通信只能靠 postMessage + onmessage
主线程和 Worker 完全隔离,没有共享内存,也不能互相调用函数。所有交互必须走消息通道,底层用的是结构化克隆算法(Structured Clone)。
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
能传的数据类型包括:
— 字符串、数字、布尔、null、数组、纯对象(JSON-safe)、ArrayBuffer、TypedArray、Blob、FormData
— 不能传:function、undefined、Symbol、Date(建议转成 getTime())、RegExp、Promise、DOM 节点
典型流程:
- 主线程发:
worker.postMessage({ action: 'filter', list: bigArray }); - Worker 收:
self.onmessage = (e) => { const { action, list } = e.data; ... }; - Worker 回传:
self.postMessage({ result: filteredList }); - 主线程收:
worker.onmessage = (e) => { console.log(e.data.result); };
Worker 里能做什么、不能做什么
Worker 有自己的全局对象 self(不是 window),所以很多前端常用 API 都不可用:
- ✅ 可用:
console.log(输出在 DevTools 的 Workers 标签页)、fetch、setTimeout、navigator、location、importScripts()(加载其他 JS 文件) - ❌ 不可用:
document、window、localStorage、alert、parent、任何 DOM 操作方法(getElementById等) - ⚠️ 注意:
XMLHttpRequest可用但已过时,优先用fetch;localStorage虽然同源,但 Worker 里根本没这个 API
如果业务需要操作 DOM,必须由主线程完成:Worker 处理完数据 → 发回主线程 → 主线程用结果更新页面。










