本文展示 WebWorker 在前端开发中的实际应用场景。实现批量视频第一帧提取并生成缩略图的功能、大数组排序和实时 CSV 数据解析。每个示例包含完整的代码,结合 Tailwind CSS 优化 UI,确保代码清晰、类型安全且易于理解。准备好让 WebWorker 帮你把重活干了吧!
npm create vite@latest webworker-examples -- --template vue-ts
cd webworker-examples
npm install
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p
npm run dev
在 src/style.css
中添加:
@tailwind base;
@tailwind components;
@tailwind utilities;
更新 vite.config.ts
:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
css: {
postcss: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
},
})
无额外运行时依赖,使用浏览器原生 WebWorker 和 API。
在一个视频管理应用中,用户上传多个视频文件,页面需要快速生成每个视频的第一帧作为缩略图。直接在主线程处理会导致页面卡顿。使用 WebWorker 在后台提取帧并生成缩略图,主线程负责渲染结果,保持 UI 流畅。
ArrayBuffer
(通过 Transferable
优化传输)。
和
API 提取第一帧,生成缩略图的 Base64 数据。src/App.vue
)
WebWorker 示例:批量视频缩略图生成
{{ error }}
{{ thumb.fileName }}
src/thumbnailWorker.ts
)interface VideoMessage {
fileName: string;
buffer: ArrayBuffer;
}
interface Thumbnail {
fileName: string;
dataUrl: string;
}
self.onmessage = async (event: MessageEvent<VideoMessage>) => {
const { fileName, buffer } = event.data;
try {
const blob = new Blob([buffer], { type: 'video/mp4' });
const url = URL.createObjectURL(blob);
const video = document.createElement('video');
video.src = url;
video.muted = true;
await new Promise<void>((resolve, reject) => {
video.onloadedmetadata = () => resolve();
video.onerror = () => reject(new Error('无法加载视频'));
});
video.currentTime = 0;
await new Promise<void>((resolve) => {
video.onseeked = () => resolve();
});
const canvas = new OffscreenCanvas(320, 180);
const ctx = canvas.getContext('2d');
if (!ctx) throw new Error('无法获取 Canvas 上下文');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
const blob = await canvas.convertToBlob({ type: 'image/jpeg', quality: 0.8 });
const dataUrl = await blobToDataUrl(blob);
URL.revokeObjectURL(url);
self.postMessage({ fileName, dataUrl });
} catch (err) {
console.error(`处理 ${fileName} 失败:`, err);
}
};
function blobToDataUrl(blob: Blob): Promise<string> {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.readAsDataURL(blob);
});
}
ArrayBuffer
传递给 Worker,使用 Transferable
优化大数据传输。
加载视频,跳转到第一帧,使用 OffscreenCanvas
绘制帧并生成 JPEG 缩略图,返回 Base64 数据。thumbnails
存储缩略图数据,实时更新 UI。Thumbnail
和 VideoMessage
接口,确保类型安全。file://
协议不支持 Worker。在一个数据分析应用中,用户需要对一个包含数十万条数据的数组进行排序。主线程直接排序会导致页面卡顿。使用 WebWorker 在后台排序,主线程保持流畅。
src/components/ArraySort.vue
)
WebWorker 示例:大数组排序
{{ error }}
排序结果(前 10 项):{{ sortedArray.slice(0, 10).join(', ') }}
src/sortWorker.ts
)self.onmessage = (event: MessageEvent<number[]>) => {
const array = event.data;
const sorted = quickSort(array);
self.postMessage(sorted);
};
function quickSort(arr: number[]): number[] {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = arr.filter(x => x < pivot);
const middle = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);
return [...quickSort(left), ...middle, ...quickSort(right)];
}
sortedArray
存储结果,显示前 10 项避免 UI 卡顿。number[]
。在一个数据导入应用中,用户上传 CSV 文件,页面需要快速解析并显示数据。主线程直接解析大文件会导致卡顿。使用 WebWorker 在后台解析 CSV,主线程渲染表格。
src/components/CsvParser.vue
)
WebWorker 示例:CSV 数据解析
{{ error }}
{{ header }}
{{ cell }}
仅显示前 10 行,共 {{ parsedData.length - 1 }} 行数据
src/csvWorker.ts
)self.onmessage = (event: MessageEvent<string>) => {
const csvText = event.data;
const parsed = parseCsv(csvText);
self.postMessage(parsed);
};
function parseCsv(text: string): string[][] {
const rows = text.split('\n').map(row => row.trim()).filter(row => row);
return rows.map(row => row.split(',').map(cell => cell.trim()));
}
parsedData
存储解析结果,显示前 10 行避免卡顿。string[][]
。if (typeof Worker === 'undefined') {
error.value = '浏览器不支持 WebWorker,请使用现代浏览器!';
}
Transferable
对象(如 ArrayBuffer
)优化大数据传输。onUnmounted
中调用 terminate
)。file://
协议不支持 Worker。Dexie.js
或其他库在 Worker 中结合 IndexedDB 存储中间结果。useWorker
)。Papa Parse
)增强 CSV 解析健壮性。本文展示了 WebWorker 在批量视频缩略图生成、大数组排序和 CSV 数据解析中的应用。WebWorker 让主线程专注于 UI 渲染,将计算密集型任务交给后台线程,确保页面流畅。结合 Tailwind CSS 和 TypeScript,代码既美观又安全,适用于视频管理、数据分析等场景。开发者可根据需求调整 Worker 任务,释放 WebWorker 的性能潜力!