大家好,我是小杨,一个和Vue相爱相杀6年的老司机。今天要聊的是个既基础又容易踩坑的话题------Vue中的懒加载。最近团队新人问我:"小杨哥,Vue 2.0是不是不能实现懒加载啊?" 我当场就笑了...
1. 先破谣言:Vue 2.x当然能懒加载!
真相 :Vue 2.x通过动态import
+异步组件
完美支持懒加载,这是ES6特性,和Vue版本无关!
javascript
// Vue 2.x 标准写法
const MyComponent = () => import('./MyComponent.vue')
2. 我的性能优化实战
场景1:路由懒加载(最常用)
javascript
// router.js
const routes = [
{
path: '/dashboard',
component: () => import('@/views/Dashboard.vue') // 关键在这!
}
]
效果:首次加载只下载当前路由的代码,其他路由等访问时再加载
场景2:组件级懒加载
javascript
// 父组件中
export default {
components: {
'my-heavy-component': () => import('./HeavyComponent.vue')
}
}
3. 原理深挖(看过源码的来)
Vue 2.x的懒加载核心是:
- webpack的代码分割(生成单独的chunk)
- Vue的异步组件工厂函数
- 底层使用Promise
源码关键点(简化版):
javascript
// vue/src/core/vdom/async-component.js
function resolveAsyncComponent(
factory: Function,
baseCtor: Class<Component>
): Class<Component> | void {
if (isPromise(factory.resolved)) {
return factory.resolved
}
const resolve = (res: Object | Class<Component>) => {
factory.resolved = ensureCtor(res, baseCtor)
if (!sync) {
forceRender(false)
}
}
const res = factory(resolve, reject) // 这里执行import()
if (isObject(res)) {
if (isPromise(res)) {
res.then(resolve, reject)
}
}
}
4. Vue 2.x懒加载的三大坑
坑① 魔法注释失效
javascript
// 有时候webpack魔法注释不生效
const Foo = () => import(/* webpackChunkName: "my-chunk" */ './Foo.vue')
解法:检查babel配置是否转译了注释
坑② 预加载时机难控
javascript
// 可能提前加载非必要资源
const Foo = () => import('./Foo.vue' /* webpackPrefetch: true */)
解法:慎用prefetch,优先用preload
坑③ 错误处理缺失
javascript
// 网络出错会白屏
const Foo = () => import('./Foo.vue')
解法:加错误边界
javascript
const Foo = () => ({
component: import('./Foo.vue'),
loading: LoadingComponent,
error: ErrorComponent,
delay: 200,
timeout: 3000
})
5. Vue 3的超级升级
Vue 3的defineAsyncComponent
更强大:
javascript
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent({
loader: () => import('./Foo.vue'),
delay: 200, // 延迟显示loading
timeout: 3000, // 超时处理
suspensible: false // 是否配合Suspense使用
})
6. 性能对比实测
我的一个项目优化数据:
方案 | 首屏体积 | LCP时间 |
---|---|---|
传统加载 | 1.2MB | 2.8s |
Vue 2.x懒加载 | 420KB | 1.4s |
Vue 3懒加载 | 380KB | 1.2s |
7. 写给新手的建议
- 路由必须懒加载:这是性价比最高的优化
- 大组件才懒加载:小于30KB的组件没必要
- 注意加载状态:一定要加loading效果
- 生产环境验证:记得检查chunk是否真的拆分
8. 高级玩法:动态懒加载
我在后台管理系统这样用:
javascript
// 根据用户权限动态加载模块
const getAdminComponent = () => {
return user.isSuperAdmin
? import('./SuperAdmin.vue')
: import('./NormalAdmin.vue')
}
最后说句大实话
"懒加载不是银弹,用不好反而会降低用户体验" ------ 这是我在性能优化分享会上反复强调的。
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!