Web Worker 的核心作用是让 JavaScript 在后台线程运行以避免阻塞主线程,它并非加速计算的银弹,而是防止页面卡死的隔离机制;其独立执行上下文支持 fetch、setTimeout 等 API,但不支持 DOM 操作和同步存储。

Web Worker 的核心作用是让 JavaScript 在后台线程运行,避免阻塞主线程的渲染和交互——它不是用来“加速计算”的银弹,而是防止页面卡死的隔离机制。
为什么主线程卡住时 Worker 仍能运行
浏览器的 JavaScript 是单线程的,所有 DOM 操作、事件响应、定时器回调都挤在同一个线程里。一旦执行一段耗时同步代码(比如 for 循环 100 万次、大数组排序、JSON 解析超大文本),整个页面就无法响应点击、滚动或动画。
Worker 启动后拥有独立的执行上下文:没有 window、没有 document、不能操作 DOM,但它有自己的 self、setTimeout、fetch 和 postMessage。这意味着:
- 主线程卡住,Worker 线程照常执行计算或网络请求
- Worker 卡住,不会影响页面滚动或按钮点击
- 两者通信只能靠异步的
postMessage和onmessage,无法共享变量或内存
创建 Worker 的两种方式及适用场景
最常用的是专用 Worker(Worker 构造函数),适用于单个脚本与一个后台任务长期协作;另一种是模块 Worker(new Worker(..., { type: 'module' })),支持 import 语法,适合拆分逻辑。
立即学习“Java免费学习笔记(深入)”;
注意路径必须是同源的,且不能是 file:// 协议(本地双击 HTML 会失败):
// main.js
const worker = new Worker('./calc-worker.js');
worker.postMessage({ data: [1, 2, 3, ..., 100000] });
worker.onmessage = (e) => {
console.log('结果:', e.data);
};
calc-worker.js 内容示例:
JS特效就是网页中实现的特殊效果或者特殊的功能的一种技术,是用网页脚本(javascript)来编写制作动态特殊效果,比如图片切换,渐变等等,它为网页活跃了网页的气氛,有时候会起到一定的亲切力。务(控制台应用程序、桌面应用程序、WEB应用程序等)
self.onmessage = function(e) {
const result = e.data.data.reduce((a, b) => a + b, 0);
self.postMessage(result); // 注意是 self.postMessage,不是 postMessage
};
常见坑:
- Worker 文件路径错误时,控制台报
Failed to load worker script,不是静默失败 - Worker 内不能用
console.log直接输出到主页面控制台(部分浏览器会显示在“Worker”标签页下) - 不能在 Worker 中调用
localStorage或indexedDB同步 API(但可用indexedDB异步接口)
Worker 中哪些 API 可用、哪些不可用
Worker 不是完整 JS 运行环境。它支持:
-
fetch、WebSocket(可发起网络请求) -
setTimeout、setInterval、requestIdleCallback -
Atomics和SharedArrayBuffer(需开启跨域策略,现代用法) -
importScripts()(传统模块加载)或import(模块 Worker)
明确不支持:
-
document、window、parent、frameElement -
localStorage、sessionStorage(同步存储) -
XMLHttpRequest(已废弃,用fetch替代) -
location对象(但可通过self.location.href读取当前 Worker 脚本 URL)
性能与调试时容易忽略的关键点
Worker 启动和消息传递都有开销。高频 postMessage(比如每毫秒发一次)反而比主线程直接算更慢,因为序列化/反序列化要复制数据。
优化建议:
- 传大数据前,优先考虑
Transferable(如ArrayBuffer),用postMessage(data, [buffer])避免拷贝 - 不要为每次小计算都新建 Worker,复用
worker.terminate()后重建成本高;可封装成 Worker 池 - Chrome DevTools 的 “Application → Service Workers” 不显示普通 Worker;要看 “Sources → Workers” 或刷新后点 “Pause on start”
- Worker 报错不会触发
window.onerror,需在 Worker 内监听self.onerror并手动上报
真正难的不是启动 Worker,而是厘清「该不该放进去」——DOM 更新、用户输入响应、轻量计算都不该进 Worker;只有确定会长时间占用 CPU 且不依赖 UI 的任务才值得隔离。










