Web Worker 用于解决 JavaScript 主线程阻塞问题,通过独立执行环境运行耗时计算任务,不访问 DOM,依赖 postMessage 通信,适合纯计算但有启动开销和兼容性限制。

Web Worker 解决的是 JS 主线程阻塞问题
HTML 本身没有“多线程”概念,但浏览器给 JavaScript 提供了 Worker 这个独立执行环境,它和页面主线程完全隔离:不能访问 DOM、window、document,也没有 alert 或 localStorage(除非显式传入)。它的存在不是为了“让 HTML 多线程”,而是让耗时脚本(比如大数组排序、图像处理、加密解密)不卡住页面交互。
主线程卡死的典型场景和 Worker 替代方案
常见错误是直接在 for 循环里做上万次计算,或用 JSON.parse 解析几 MB 的 JSON 字符串——这些都会让页面白屏、按钮失灵、滚动卡顿。Worker 是唯一能真正并行执行 JS 逻辑的方式(注意:不是“多线程”意义上的并行,而是“多上下文”并发)。
- 适合放进去的任务:
postMessage传入原始数据,Worker 内做纯计算,再用postMessage返回结果 - 不适合放进去的操作:
fetch可以用,但必须自己处理跨域;XMLHttpRequest不推荐(已过时);任何依赖document的 DOM 操作都报错 - 调试方式不同:Chrome DevTools 的
Sources面板里要展开Workers节点才能断点
Worker 创建和通信的最小可行写法
不能直接内联写 Worker 脚本(new Worker('data:text/javascript,...') 在多数浏览器被禁),必须用外部 JS 文件。通信靠 postMessage 和 onmessage,消息内容自动序列化(深层对象会被结构化克隆,函数、undefined、Symbol 会丢失)。
/* worker.js */
self.onmessage = function(e) {
const data = e.data;
const result = data.map(x => x * 2); // 纯计算
self.postMessage(result);
};/* 主线程 */
const worker = new Worker('worker.js');
worker.postMessage([1, 2, 3, 4]);
worker.onmessage = function(e) {
console.log('来自 Worker 的结果:', e.data); // [2, 4, 6, 8]
};容易被忽略的限制和兼容性坑
Worker 不是万能加速器。它启动有开销(约几毫秒),频繁创建销毁反而更慢;它不能共享内存(SharedArrayBuffer 是例外,但需开启 crossOriginIsolated,且 Safari 支持差);IE 完全不支持,旧 Android WebView 也有 bug。
立即学习“前端免费学习笔记(深入)”;
-
importScripts()只能加载同源脚本,不能用 ES Module 的import - Worker 内的
setTimeout、Promise正常工作,但requestIdleCallback不可用 - 如果主线程中
worker.terminate(),Worker 立即停止,未完成的postMessage会丢失
真要用好 Worker,关键不是“能不能跑”,而是判断任务是否足够重、是否可拆分、是否值得引入额外的通信与生命周期管理成本。











