🧠 Web Worker 通信封装与实战应用详解
🚀 收藏 + 点赞 + 关注,掌握前端处理大数据和复杂计算的核心能力!
一、为什么使用 Web Worker?
在 Web 前端中,所有的 JS 操作都运行在主线程,如果你执行的是重计算(如大数据过滤、压缩、加解密、排序等),会:
- 阻塞 UI 渲染 😵💫
- 用户体验变差(点击没反应)
- 动画/交互卡顿
💡 Web Worker = 开辟一个 JS 线程,运行在后台,与主线程通信。
🎯 场景:复杂计算 / 大数据处理 / 多线程模拟
二、使用与封装:通信核心实现
✅ 1. 最基础用法
👉 worker.js(运行在子线程):
// worker.js
self.onmessage = (event) => {
const data = event.data;
// 模拟计算密集操作
const result = data.map((n) => n * 2);
self.postMessage(result);
};
👉 主线程页面中使用:
const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });
worker.postMessage([1, 2, 3, 4]);
worker.onmessage = (e) => {
console.log('结果:', e.data); // [2, 4, 6, 8]
};
✅ 2. 通信封装:创建 WorkerManager
为了更方便统一管理多个 Worker,我们来封装一个通信管理器:
👉 WorkerManager.ts
export class WorkerManager {
private worker: Worker;
constructor(workerPath: string) {
this.worker = new Worker(new URL(workerPath, import.meta.url), { type: 'module' });
}
post<T = any, R = any>(data: T): Promise<R> {
return new Promise((resolve, reject) => {
this.worker.onmessage = (e) => resolve(e.data);
this.worker.onerror = (err) => reject(err);
this.worker.postMessage(data);
});
}
terminate() {
this.worker.terminate();
}
}
✅ 3. 封装使用:在 Vue 中调用
👉 使用 Worker 处理 10 万条数据排序:
import { WorkerManager } from '@/utils/WorkerManager';
const useHeavyCompute = async () => {
const wm = new WorkerManager('./sortWorker.js');
const list = Array.from({ length: 100000 }, () => Math.floor(Math.random() * 1000000));
const sorted = await wm.post<number[], number[]>(list);
console.log('排序完成,前 10 个:', sorted.slice(0, 10));
wm.terminate();
};
三、Vue3 实战案例:Worker + 表格虚拟滚动展示 10 万条数据
1️⃣ 目录结构
src/
├─ components/
│ └─ VirtualTable.vue
├─ workers/
│ └─ filterWorker.js
├─ utils/
│ └─ WorkerManager.ts
2️⃣ filterWorker.js
self.onmessage = ({ data }) => {
const { list, keyword } = data;
const result = list.filter((item) => item.name.includes(keyword));
self.postMessage(result);
};
3️⃣ VirtualTable.vue
<template>
<div>
<el-input v-model="keyword" placeholder="搜索" @input="filterList" />
<el-table :data="filtered" height="500">
<el-table-column prop="id" label="ID" />
<el-table-column prop="name" label="名称" />
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { WorkerManager } from '@/utils/WorkerManager';
const list = ref(Array.from({ length: 100000 }, (_, i) => ({ id: i + 1, name: `名称${i + 1}` })));
const filtered = ref([...list.value]);
const keyword = ref('');
const filterList = async () => {
const wm = new WorkerManager('@/workers/filterWorker.js');
const result = await wm.post({ list: list.value, keyword: keyword.value });
filtered.value = result;
wm.terminate();
};
</script>
四、总结建议 ✨
方案 | 说明 |
---|---|
基础 Worker | 利用 postMessage / onmessage 传值 |
封装类 | 更利于复用、统一管理 Worker 生命周期 |
Vue 实战 | 结合大数据列表 / 虚拟滚动使用效果最佳 |
🧩 常见问题 FAQ
问题 | 解法 |
---|---|
Worker 不能访问 DOM? | 是的,Worker 运行在独立线程,不能访问 window 或 document |
Vue3 中路径不识别 Worker? | 使用 new URL('./xxx.js', import.meta.url) 指定路径 |
Worker 占用内存怎么办? | 用完后 terminate() 手动销毁 |
🏁 结语
使用 Web Worker 是前端提升性能的强大武器,尤其适合大数据或复杂计算场景。
📦 Worker 可搭配使用的场景包括:
- 数据导入解析(如 CSV、Excel)
- 图像处理(灰度、滤镜)
- 实时图表计算(Echarts 动态数据)
- AI 模型推理(TinyML)
- 语音转文字、实时字幕(Web Speech API)