告别页面卡死!Vue3 + WebWorker 性能优化实战

你遇到过点击按钮后页面直接"假死"的情况吗?Loading 动图定格、按钮点击无效、甚至浏览器弹出"未响应"警告?别慌,这通常是 JS 主线程被密集计算阻塞了。今天,带你用 Web Worker 把这些重活"踢"出主线程,让你的 Vue3 应用丝滑如初!

😱 案发现场:一段代码让浏览器"脑梗"

在 B 端系统中,我们经常会遇到这种需求:

  • 导出 Excel :处理几万条数据的格式化。
  • 图像处理 :前端压缩图片或添加水印。
  • 复杂算法 :加密解密、大数计算(如斐波那契数列)。

很多同学反手就是直接写在组件里:

javascript 复制代码
// ❌ 危险操作:在主线程进行 CPU 密集型计算
function expensiveCalculation() {
  const result = fibonacci(42); // 这里可能要算好几秒
  console.log(result);
}

结果就是: 只要计算还在跑,浏览器的 UI 渲染线程就被挂起。 你的 Loading 圈不转了,用户的鼠标点击没反应了,整个页面像中了定身术一样,就像下图中加载动画卡主了。

💡 救星登场:Web Worker

JavaScript 是单线程的,但浏览器不是! Web Worker 的作用就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。
简单说:主线程负责貌美如花(UI 渲染),Worker 线程负责赚钱养家(脏活累活)。

🛠️ 实战:Vue3 中使用 Web Worker

今天我们就通过一个 斐波那契数列计算 的 Demo,来看看 Worker 到底有多强。
1. 准备 Worker 脚本

首先,我们需要编写一个独立的 JS 文件,它运行在独立的线程中。

javascript 复制代码
// src/utils/webWorker.js
// 监听主线程发来的消息
self.onmessage = function (e) {
  const { type, data } = e.data;

  if (type === "FIBONACCI_CALC") {
    const start = performance.now();
    // 执行耗时计算
    const result = fibonacci(data);
    const time = performance.now() - start;

    // 计算完毕,把结果发回给主线程
    self.postMessage({
      type,
      data: result,
      time: time.toFixed(2)
    });
  }
};

// 递归计算斐波那契数列(故意用性能差的递归来模拟耗时任务)
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

2. 在 Vue 组件中引入

在 Vite 构建的 Vue3 项目中,引入 Worker 非常优雅,只需要加上 ?worker 后缀。

javascript 复制代码
// src/views/func/performance/webWorker.vue
<script setup>
import { ref } from 'vue';
// ✅ Vite 专属写法,简单粗暴
import MyWorker from "@/utils/webWorker.js?worker";

const calculateNum = ref(42);
const loading = ref(false);

const runWorker = () => {
  loading.value = true;

  // 1. 实例化 Worker
  const worker = new MyWorker();

  // 2. 发送任务
  worker.postMessage({
    type: "FIBONACCI_CALC",
    data: calculateNum.value,
  });

  // 3. 接收结果
  worker.onmessage = (e) => {
    const { data, time } = e.data;
    console.log(`计算结果:${data},耗时:${time}ms`);

    // 页面状态照常更新,丝毫不卡!
    loading.value = false;

    // 4. 用完记得销毁,释放内存
    worker.terminate();
  };
};
</script>

3. 效果对比

为了直观展示,我做了一个 帧率计数器 。

方案 A(主线程) :点击开始计算,帧率计数器瞬间 停止跳动 ,浏览器卡死,直到计算结束。用户体验极差!❌

方案 B(Worker) :点击开始计算,后台在狂奔,但前台的帧率计数器 依然流畅跳动 ,Loading 动画丝滑旋转。用户体验满分!✅

📝 核心知识点总结

1. 什么时候用 Worker?

①任何超过 50ms 的纯计算任务。

②大文件上传前的切片、Hash 计算。

③复杂数据的过滤、排序、格式化。

④Canvas 图像像素级处理。
2. 注意事项

①DOM 限制 :Worker 内无法操作 DOM(不能 document.getElementById )。

②通信成本 :主线程和 Worker 之间传递数据是通过拷贝而非共享,传输过③大的数据(如几百 MB 的 JSON)本身也会消耗性能。建议使用 Transferable Objects 传输二进制数据。

④同源策略 :Worker 脚本必须遵守同源策略。
3. Vite 黑科技

a.直接作为模块引入。
import Worker from './worker.js?worker'

b.多个标签页共享同一个 Worker。
import SharedWorker from './worker.js?sharedworker'

源码地址

https://gitee.com/benxiaohai1071/bxh-admin-vue3/blob/master/src/views/func/performance/webWorker.vue

相关推荐
逍遥德3 小时前
如何学编程之理论篇.03.如何做数据库表结构设计?
开发语言·数据库·性能优化·代码规范·代码复审
知识即是力量ol3 小时前
口语八股——Redis 面试实战指南(终篇):集群与高可用篇、性能优化篇、面试回答技巧总结
redis·面试·性能优化·八股·集群与高可用·回答技巧
a285283 小时前
最新SQL Server 2022保姆级安装教程【附安装包】
数据库·性能优化
钛态4 小时前
Flutter for OpenHarmony:leak_tracker 自动监测内存泄漏,精准定位未释放对象(内存性能优化) 深度解析与鸿蒙适配指南
flutter·华为·性能优化·harmonyos
野犬寒鸦5 小时前
CompletableFuture 在 项目实战 中 创建异步任务 的核心优势及使用场景
java·服务器·后端·性能优化
he___H6 小时前
jvm48-96回
java·jvm·性能优化
玩c#的小杜同学21 小时前
工业级稳定性:如何利用生产者-消费者模型(BlockingCollection)解决串口/网口高频丢包问题?
笔记·学习·性能优化·c#·软件工程
工业HMI实战笔记1 天前
机床设备HMI:加工参数可视化与故障诊断界面
ui·性能优化·自动化·汽车·交互
yuanmenghao1 天前
Linux 性能实战 | 第 20 篇:trace-cmd 与 kernelshark 可视化分析 [特殊字符]
linux·python·性能优化