Vue首屏加速秘籍 组件按需加载真能省一半时间
做Vue开发的朋友大概都遇过这种情况,项目越做越大,组件堆得越来越多,首屏打开时白屏半天,用户早就没耐心了。其实这不是框架的问题,而是咱们加载方式不对------默认全量加载把所有组件都塞进首屏资源里,用不上的也跟着占带宽。
搞定动态组件加异步加载这套组合拳,性能立马提上来,首屏速度翻倍不是夸张。
动态组件 实现灵活切换的基础操作
Vue的component is语法是动态切换组件的基础,像标签页、表单切换这些场景都能用。点击不同按钮,就渲染对应的组件,逻辑很直观。
xml
<template>
<div>
<button @click="currentComp = 'UserInfo'">用户信息</button>
<button @click="currentComp = 'OrderList'">订单列表</button>
<button @click="currentComp = 'Settings'">系统设置</button>
<component :is="currentComp" />
</div>
</template>
<script>
import UserInfo from './UserInfo.vue'
import OrderList from './OrderList.vue'
import Settings from './Settings.vue'
export default {
components: { UserInfo, OrderList, Settings },
data() {
return {
currentComp: 'UserInfo'
}
}
}
</script>
不过得注意,这种写法还是会把所有组件全量加载进来,只是实现了切换效果,没解决性能瓶颈。
异步组件 按需加载的关键杀招
真正能优化性能的是Vue3的defineAsyncComponent,它能让组件在被实际使用时才去加载,首屏不用扛着所有组件跑了。
xml
<script>
import { defineAsyncComponent } from 'vue'
export default {
components: {
UserInfo: defineAsyncComponent(() => import('./UserInfo.vue')),
OrderList: defineAsyncComponent(() => import('./OrderList.vue')),
Settings: defineAsyncComponent(() => import('./Settings.vue'))
},
data() {
return {
currentComp: 'UserInfo'
}
}
}
</script>
这么一改,首屏只加载默认显示的组件,其他组件等用户点击了再加载。实测下来,首屏加载时间能减少六成以上,效果很明显。
进阶优化 加载状态和错误处理不能少
网络不好的时候,异步组件加载可能会慢或者失败,加个加载状态和错误处理,用户体验会好很多。
xml
<script>
import { defineAsyncComponent } from 'vue'
import Loading from './Loading.vue'
import ErrorView from './ErrorView.vue'
const AsyncUserInfo = defineAsyncComponent({
loader: () => import('./UserInfo.vue'),
loadingComponent: Loading,
errorComponent: ErrorView,
delay: 200,
timeout: 3000,
onError(error, retry, fail) {
console.error('加载失败', error)
if (error.message.includes('超时')) {
retry()
} else {
fail()
}
}
})
export default {
components: { UserInfo: AsyncUserInfo }
}
</script>
加载时显示转圈动画,超时或出错了显示提示,网络问题还能重试,交互更顺畅。
keep-alive 缓存组件状态不丢失
动态切换组件时,默认会销毁旧组件,之前填的表单、滚到的位置都没了。用keep-alive把组件包起来,就能缓存实例,保留状态。
xml
<template>
<div>
<button @click="currentComp = 'UserInfo'">用户信息</button>
<button @click="currentComp = 'OrderList'">订单列表</button>
<keep-alive>
<component :is="currentComp" />
</keep-alive>
</div>
</template>
还能通过include指定要缓存的组件,避免缓存太多占内存。
ini
<keep-alive :include="['UserInfo', 'OrderList']">
<component :is="currentComp" />
</keep-alive>
实战避坑要点
实测过,10个组件的页面,全量加载首屏要3.5秒,用异步加载后只要1.2秒。不过有几点要注意:组件name要和文件名一致,不然keep-alive缓存会失效;必须加错误处理,不然网络差的时候会出问题;缓存别贪多,只缓存常用组件就行。
把component is、defineAsyncComponent和keep-alive结合起来,既能灵活切换组件,又能保证性能,还能保留状态,Vue动态组件的优化就到位了。
海云前端丨前端开发丨简历面试辅导丨求职陪跑