在开始使用Web Workers之前,首先让我们先了解一下什么是Web Workers
Web Workers 是一种在浏览器后台独立于主线程运行的 JavaScript 线程,它允许在 Web 应用程序中进行后台和长时间运行的脚本处理,而不会影响用户的界面性能。Web Workers 通过在后台线程中执行 JavaScript 脚本来实现这一点,从而避免了阻塞主线程。
为什么使用 Web Workers?
- 提高性能:
- 避免长时间运行的脚本导致用户界面冻结或变得无响应。
- 允许并行执行任务,提高计算密集型任务的效率。
- 后台处理:
- 可以执行长时间运行的任务,如文件压缩、图像处理等,而不影响用户交互。
- 数据处理:
- 对于大数据集的操作非常适合使用 Web Workers,比如数据分析或复杂的算法运算。
- 游戏开发:
- 在游戏开发中,可以用来处理 AI 计算、物理模拟等,以保持游戏画面流畅。
- 离线应用:
- 可以用于处理离线存储的数据同步和其他后台任务。
- 资源加载:
- 加载和解析大型 JSON 文件或其他数据结构时,可以避免阻塞主线程。
但是其实在实际开发应用中,Web Workers使用的最多的应该就是在大文件分片上传对文件进行md5的计算,因为此时浏览器需要耗费大量的性能去对文件分出的每一片进行一个计算。
使用 Web Workers 的注意事项:
- 通信:主脚本和 Worker 之间通过消息传递机制进行通信。这意味着你需要发送消息给 Worker,并且 Worker 也需要能够发送消息回主脚本。
- 资源限制:虽然 Web Workers 可以帮助提高性能,但它们仍然受限于浏览器的资源限制,例如每个页面的并发 Worker 数量。
- API 支持:并非所有浏览器 API 都可以在 Worker 中使用。例如,DOM 相关的 API 通常不可用。
下面我将会在Vue3中,给大家使用Web Workers用来处理大数据的实战
我们先生成10000000条大数据,并对这些所有数据进行处理
const bigDataArray = Array(10000000)
.fill(0)
.map((_, i) => {
return {
num: i,
text: "我去你的" + i,
img: "这是一个图片" + i,
img1: "这是一个图片",
img2: "这是一个图片",
img3: "这是一个图片",
};
});
接下来,我要把这个i变成i*2,用来模拟数据处理,观察使用web worker处理所需时间
// 获取电脑的cpu核数,一般有几核就开启多少个现场
let cpuNum = navigator.hardwareConcurrency || 6;
// 看每个线程处理多少个数据
const chunk = Math.ceil(bigDataArray.length / cpuNum);
const handleClick = async () => {
const res = await handleInfo();
console.log(res);
};
const handleInfo = () => {
return new Promise((resolve, reject) => {
// 当要处理的数据量比核数少的时候,开启少的核数
if (cpuNum > bigDataArray.length / chunk) {
cpuNum = Math.ceil(bigDataArray.length / chunk);
}
const chunkRes: any = [];
// 看他是否完成
let finishCount = 0;
for (let i = 0; i < cpuNum; i++) {
let start = i * chunk;
let end = (i + 1) * chunk;
if (end > bigDataArray.length) {
end = bigDataArray.length;
}
const worker = new Worker(getWorker("dataWorker"), { type: "module" });
// 使用postMessage王worker传值
worker.postMessage({
bigData: bigDataArray.slice(start, end),
end,
start,
});
worker.onmessage = (e) => {
const { processedData, startIndex } = e.data;
// 将处理结果放回正确位置
for (let j = 0; j < processedData.length; j++) {
chunkRes[startIndex + j] = processedData[j];
}
// 关闭webWorker
worker.terminate();
finishCount++;
if (finishCount === cpuNum) {
resolve(chunkRes);
}
};
}
});
};
web worker中的函数
const hanglerData = (bigDataArray: any, index: number) => {
// console.log(bigDataArray,index)
// 如果需要做其他处理在这里操作
};
// 在 Worker 中,处理数据并返回
onmessage = async (event) => {
const { bigData, start } = event.data;
// 处理数据
const processedData = bigData.map((item:any) => {
// 执行你的处理逻辑
return item; // 示例:简单返回
});
postMessage({ processedData, startIndex: start });
};
观察结果可以看到,使用web Worker进行数据处理之后,速度比单纯进行处理要快了不少