2 Star 4 Fork 0

笨小孩丶/bxh-admin-vue3

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
webWorker.vue 5.26 KB
一键复制 编辑 原始数据 按行查看 历史
笨小孩丶 提交于 2026-02-14 00:28 +08:00 . 第一次提交
<template>
<div class="worker-demo-container">
<el-card class="header-card">
<template #header>
<div>
<span>Web Worker 核心优势演示</span>
</div>
</template>
<div class="ui-monitor">
<div class="monitor-info">
<div class="frame-counter">{{ frameCount }}</div>
</div>
<div class="monitor-desc">
注意:如果下方数字<b>停止跳动</b>,说明主线程被 JS
阻塞,浏览器无法处理 UI 更新。
</div>
</div>
</el-card>
<div class="control-panel">
<el-form inline>
<el-form-item label="计算规模 (斐波那契第 N 项):">
<el-input-number v-model="calculateNum" :min="30" :max="45" />
<span class="tip-text">建议设为 42 左右</span>
</el-form-item>
</el-form>
</div>
<el-row :gutter="20">
<el-col :span="12">
<el-card shadow="never" class="demo-card block-mode">
<template #header
><b style="color: #f56c6c">方案 A:主线程直接计算</b></template
>
<p class="desc">计算函数在主线程执行,会抢占 UI 渲染的时间片。</p>
<el-button
type="danger"
@click="runMainThread"
:loading="mainLoading"
>
开始计算 (会卡死)
</el-button>
<div v-if="mainResult !== null" class="result-area">
<p>计算结果: {{ mainResult }}</p>
<p>耗时: {{ mainTime }} ms</p>
</div>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="never" class="demo-card worker-mode">
<template #header
><b style="color: #67c23a">方案 B:Web Worker 异步计算</b></template
>
<p class="desc">计算在独立线程执行,主线程继续负责 60fps 的渲染。</p>
<el-button type="success" @click="runWorker" :loading="workerLoading">
开始计算 (依然流畅)
</el-button>
<div v-if="workerResult !== null" class="result-area">
<p>计算结果: {{ workerResult }}</p>
<p>耗时: {{ workerTime }} ms</p>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup name="webWorker">
import MyWorker from "@/utils/webWorker.js?worker";
const { proxy } = getCurrentInstance();
const calculateNum = ref(42);
const frameCount = ref(0);
let animationId = null;
// --- 活性监视逻辑 ---
const updateMonitor = () => {
frameCount.value++;
animationId = requestAnimationFrame(updateMonitor);
};
onMounted(() => {
updateMonitor();
});
onBeforeUnmount(() => {
if (animationId) cancelAnimationFrame(animationId);
if (workerInstance) workerInstance.terminate();
});
// --- 方案 A: 主线程逻辑 ---
const mainLoading = ref(false);
const mainResult = ref(null);
const mainTime = ref(null);
const runMainThread = () => {
mainLoading.value = true;
// 给 Vue 一个渲染 loading 状态的小机会
setTimeout(() => {
const start = performance.now();
mainResult.value = fibonacciInternal(calculateNum.value);
const end = performance.now();
mainTime.value = (end - start).toFixed(2);
mainLoading.value = false;
proxy.$modal.msgError(`主线程计算完毕,刚才页面完全动不了!`);
}, 50);
};
function fibonacciInternal(n) {
if (n <= 1) return n;
return fibonacciInternal(n - 1) + fibonacciInternal(n - 2);
}
// --- 方案 B: Worker 逻辑 ---
const workerLoading = ref(false);
const workerResult = ref(null);
const workerTime = ref(null);
let workerInstance = null;
const runWorker = () => {
workerLoading.value = true;
if (!workerInstance) {
workerInstance = new MyWorker();
}
workerInstance.postMessage({
type: "FIBONACCI_CALC",
data: calculateNum.value,
});
workerInstance.onmessage = (e) => {
const { type, data: resultData, time } = e.data;
if (type === "FIBONACCI_CALC") {
workerResult.value = resultData;
workerTime.value = time;
workerLoading.value = false;
// 用完记得销毁,释放内存
workerInstance.terminate();
}
proxy.$modal.msgSuccess(`Worker 计算完毕,期间 UI 没有任何卡顿!`);
};
};
</script>
<style scoped>
.worker-demo-container {
padding: 24px;
background-color: #f5f7fa;
min-height: 100vh;
}
.header-card {
margin-bottom: 20px;
}
.ui-monitor {
display: flex;
align-items: center;
gap: 40px;
background: #2b2f3a;
color: white;
padding: 20px;
border-radius: 12px;
}
.frame-counter {
font-family: "Courier New", monospace;
font-size: 42px;
color: #409eff;
font-weight: bold;
line-height: 1;
}
.monitor-desc {
flex: 1;
font-size: 14px;
color: #a8abb2;
border-left: 1px solid #4e525a;
padding-left: 20px;
}
.control-panel {
margin-bottom: 20px;
background: white;
padding: 15px;
border-radius: 8px;
}
.demo-card {
min-height: 280px;
}
.block-mode {
border-top: 4px solid #f56c6c;
}
.worker-mode {
border-top: 4px solid #67c23a;
}
.desc {
font-size: 14px;
color: #606266;
height: 40px;
}
.result-area {
margin-top: 20px;
padding: 12px;
background: #f0f2f5;
border-radius: 4px;
}
.tip-text {
margin-left: 10px;
color: #909399;
font-size: 12px;
}
</style>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/benxiaohai1071/bxh-admin-vue3.git
git@gitee.com:benxiaohai1071/bxh-admin-vue3.git
benxiaohai1071
bxh-admin-vue3
bxh-admin-vue3
master

搜索帮助