tip:总结不全,项目中遇到的,后续补充
页面卡顿原因有:渲染组件过多,代码执行时间长
页面渲染组件过多
1. 懒加载
用于循环生成el-select的情况:使用
isEdit
控制显示或隐藏select组件。div
模拟一个select,用exclude_reason
显示内容
1.1 变量控制
<div v-if="!isEdit" class="el-input el-input--suffix el-input--mini" style="width: 100%" @click="clickIsEdit(row)">
<div class="el-input__inner" style="width: 100%" :style="exclude_reason ? '' : 'color: #c1c4cc'">
{{ exclude_reason ? '选中的数据' : '选择屏蔽原因' }}
</div>
<span class="el-input__suffix">
<span class="el-input__suffix-inner">
<i class="el-select__caret el-input__icon el-icon-arrow-down" />
</span>
</span>
</div>
<el-select
v-else
ref="selectRef"
:value="exclude_reason"
size="mini"
placeholder="选择原因"
filterable
style="width:100%"
@visible-change="visible => !visible&&(isEdit = false)"
@change="changeExcludeReason()"
>
<el-option v-for="item in reasonsForBlockingList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
clickIsEdit(row) {
row.isEdit = true
this.$nextTick(() => {
this.$refs.selectRef?.toggleMenu()
})
},
changeExcludeReason(){
},
对于路由和组件,使用懒加载以减少初始加载时间。
1.2 路由懒加载
const routes = [
{
path: '/example',
component: () => import('@/components/ExampleComponent.vue')
}
]
1.3 组件懒加载
const ExampleComponent = () => import('@/components/ExampleComponent.vue')
2. 虚拟滚动
如果页面涉及大量数据的渲染(如表格、列表),可以使用虚拟滚动(virtual scroll)技术。库如 Vue Virtual Scroller 可以高效地只渲染可见区域的数据。根据需求不同,使用工具不同.
npm install vue-virtual-scroller
import { RecycleScroller } from 'vue-virtual-scroller'
<recycle-scroller
:items="items"
:item-size="50"
>
<template v-slot="{ item, index }">
<!-- 渲染项目 -->
</template>
</recycle-scroller>
代码执行时间过长
1. webworker
webworker是运行在浏览器后台的一个单独的线程,可以执行一些耗时的操作而不阻塞主线程.
比如大量复杂的数据计算。双进程可实时进行通信,主要使用onmessage和postmessage两个方法。
// worker.js
onmessage = function (e) {
// onmessage获取传入的值
let res = e.data || 0;
for (let i = 0; i < 50000; i++) {
for (let i = 0; i < 100000; i++) {
res += i;
}
}
// 将计算的结果传递出去
postMessage(res);
};
vue2
安装worker-loader
,npm i worker-loader
,修改配置vue.config.js
//vue.config.js
chainWebpack: config => {
// set worker-loader
config.module
.rule('worker')
.test(/.worker.js$/)
.use('worker-loader')
.loader('worker-loader')
.end();
},
// index.vue
import Worker from '@/workers/worker.js';
mounted() {
this.workerRef = new Worker();
const start = performance.now();
this.workerRef.postMessage(0);
this.workerRef.onmessage = e => {
console.log('计算结果:', e.data);
const end = performance.now();
console.log('计算耗时:', end - start);
};
}
注意: 如果没有vue.config.js的项目,引入worker文件时,直接把路径加在worker-loader后,
import Worker from 'worker-loader!../../workers/worker.js';
vue3+vite
vite编译时直接支持worker,因此只需要编译时保证正常编译即可
/// vite.config.js
worker: {
rollupOptions: {
output: {
assetFileNames: 'assets/[name].[ext]'
}
}
},
直接引用
// index.vue
onMounted(()=>{
workerRef.value = new Worker(new URL('@/workers/worker.js', import.meta.url));
})