将耗时计算移入 Web Worker 可避免主线程卡顿,需精准筛选超16ms的纯CPU任务(如大数组排序、图像处理),用 ArrayBuffer 零拷贝通信,主线程响应更新状态,及时终止 Worker 防资源泄漏。

直接把耗时计算放进 Web Worker,主线程就能继续响应点击、滚动和动画——这是 JS 里解决卡顿最实在的办法。关键不是“加个 Worker”,而是搬得准、传得轻、接得稳。
只搬真正该搬的任务
不是所有计算都适合进 Worker。重点筛选单次执行超过 16ms 的纯 CPU 任务,比如:
- 大数组排序(万级及以上)
- 图像像素批量处理(如灰度化、卷积滤波)
- 文件内容哈希计算(SHA-256、MD5 等)
- 复杂数学运算(如模拟物理引擎、路径规划)
像简单的对象遍历、小数据过滤、状态合并这类操作,进 Worker 反而增加通信开销,得不偿失。
用好 postMessage + ArrayBuffer 实现高效通信
主线程和 Worker 之间不能共享内存,靠 postMessage 传递数据。普通 JSON 会触发结构化克隆,大数据量时慢且占内存。优化方式是:
- 传原始二进制数据时,用
ArrayBuffer配合transferable选项,实现零拷贝 - 例如处理图像:主线程调用
getImageData后,取data.buffer,用postMessage(data.buffer, [data.buffer])发给 Worker - Worker 接收后直接用
new Uint8ClampedArray(buffer)操作像素,不复制、不解析
在主线程中自然接入响应式逻辑
Worker 返回结果后,要让 UI 及时更新,但不能在 Worker 里操作 DOM 或直接改 Vue/React 状态。正确做法是:
- 主线程监听
worker.onmessage,拿到结果后同步更新ref、reactive或useState - 避免在 Worker 中做副作用(如发请求、读 localStorage),它只负责计算
- 如果计算过程需要分阶段反馈(如进度条),Worker 可多次
postMessage带 type 字段区分('progress'/'done')
记得清理,别让 Worker 白跑
Worker 一旦创建就会持续运行,不手动终止会一直占用资源。尤其在组件卸载、路由跳转时:
- Vue 中可在
onBeforeUnmount调用worker.terminate() - React 中在
useEffect清理函数里调用worker.terminate() - 如果 Worker 是复用的(如全局计算服务),可用引用计数或事件订阅机制管理生命周期











