Web Worker

319 阅读4分钟

Web Worker 使用场景以及开发中使用的API

Web Worker 主要应用在以下几类场景:


1. 大量计算、复杂算法

场景描述

当你在网页里执行复杂计算(如加密、排序、大量数据处理)时,如果放在主线程处理,会导致网页卡顿甚至「未响应」。

典型例子

  • 密码加密/解密(如 AES、RSA)
  • 大量数组排序、矩阵计算、图像像素处理
  • 游戏中复杂的物理引擎模拟(碰撞检测、大量粒子系统)

为什么用 Worker?

✅ 把重计算放到 Worker 后,主线程依然流畅地响应用户输入、动画、点击等操作。


2. 后台数据处理 / 格式转换

场景描述

前端有时候需要处理后端返回的大批量数据,比如 JSON 解析、格式转换、日志分析等。

典型例子

  • 解析超大 JSON 文件(比如几 MB 到几百 MB)
  • 把后端数据处理成前端需要的结构
  • 大量日志文件搜索、过滤、重组

为什么用 Worker?

✅ 主线程负责展示 UI,Worker 在后台慢慢处理,不让用户界面卡死。


3. 文件处理(图片、音频、视频)

场景描述

文件上传前,前端经常要做一些处理,比如压缩图片、预处理音频、分片视频。

典型例子

  • 大图片上传前压缩(比如从 10MB 压成 500KB)
  • 读取图片像素,生成缩略图
  • 音频转码、视频分段(比如直播推流)

为什么用 Worker?

✅ 文件处理通常是重 CPU 操作,交给 Worker,可以让用户界面不卡顿还能实时看到进度条。


4. 多线程并行提升性能

场景描述

一些场景可以利用「多个 Worker」来并行处理,提高整体性能,比如分块处理、分布式计算。

典型例子

  • 大数据量分块排序、再合并
  • 并行请求多个接口,统一处理结果
  • 分批渲染大量图表、节点

为什么用 Worker?

✅ 多线程让任务更快完成,同时保持页面顺滑。


5. 离线操作 / 长连接保持

场景描述

一些需要「长时间运行」或者「后台持续监听」的功能,比如和服务器保持 WebSocket 连接、离线处理任务。

典型例子

  • 后台 WebSocket 通信(长连接、推送消息)
  • Service Worker 辅助离线缓存(这属于另一种 Worker)
  • 离线笔记应用的本地存储同步

为什么用 Worker?

✅ Worker 可以常驻后台,接收服务器推送消息或处理本地事务,主线程专注界面。


Web Worker 基础与 API 整理

Worker 线程内部 API

self.postMessage(data)
// 向主线程发送消息。

self.onmessage
// 监听主线程发过来的消息,接收数据(可绑定多个监听器)。

MessageEvent
// 主线程发过来的消息对象,属性如 data(具体内容)、origin、source。

self.close()
// 手动关闭 Worker,结束执行。

self.onerror
// 捕获 Worker 内部运行错误,错误冒泡到这里。

self.onmessageerror
// 捕获消息传递时结构化克隆失败(比如发送循环引用对象)。

主线程 API

new Worker(url, options)
// 创建一个新的 Worker 实例,url 为 Worker 脚本路径。

worker.postMessage(data, transfer)
// 向 Worker 发送消息,第二个参数可用于传递 Transferable 对象。

worker.onmessage
// 监听 Worker 发送回来的消息,接收数据。

worker.onerror
// 捕获 Worker 抛出的错误(运行时异常)。

worker.onmessageerror
// 捕获发送给 Worker 消息时结构化克隆失败(如循环引用对象)。

worker.terminate()
// 主动终止 Worker 线程,立即停止 Worker 内的代码执行。

主线程的使用案例

// 创建 Worker
const worker = new Worker('worker.js');

// 发送消息到 Worker
worker.postMessage({ a: 1, b: 2 });

// 接收 Worker 返回的消息
worker.onmessage = function(e) {
  console.log('主线程收到:', e.data);
};

// 监听 Worker 错误
worker.onerror = function(e) {
  console.error('Worker 出错:', e.message);
};

// 监听消息克隆失败
worker.onmessageerror = function(e) {
  console.error('消息克隆失败:', e);
};

// 终止 Worker
worker.terminate();

小结

应用类型举例为什么适合用 Worker?
复杂计算密码加密、物理引擎避免主线程阻塞
大数据处理大 JSON 文件、日志处理保持 UI 流畅
文件处理图片压缩、音频转码节省主线程资源
并行计算分块处理、大量接口并发提高整体处理效率
长连接保持WebSocket 通信、推送后台常驻,轻量运行

📌 总之

核心原因主线程只负责交互渲染
繁重工作交给 Worker 子线程
保证用户体验不被阻塞