前言
在构建大型单页应用(SPA)时,JavaScript 包体积(Bundle Size)往往会随着业务增长而膨胀,导致首屏加载缓慢、白屏时间长。懒加载(Lazy Loading)是解决这一问题的核心方案。其本质是将代码分割成多个小的 chunk,仅在需要时才从服务器下载。
一、 路由懒加载:按需拆分页面
1. 为什么需要路由懒加载?
如果不使用懒加载,所有路由对应的组件都会被打包进同一个app.js中。用户访问首页时,浏览器不得不下载整个应用的逻辑,造成严重的性能浪费。
2. 实现方式:ESimport()
利用动态导入语法,打包工具(如 Vite 或 Webpack)会自动进行代码分割(Code Splitting)。
// router/index.ts import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'; // 静态导入:会随着主包一起加载,适合首页 import Home from '@/views/Home.vue'; const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // 动态导入:只有访问 /about 路径时,浏览器才会请求该组件对应的 JS 文件 component: () => import('@/views/About.vue') } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;二、 组件懒加载:细粒度控制
有些组件(如弹窗、复杂的图表、第三方重型库)并不需要在页面初次渲染时立即存在。
1. Vue 3 的defineAsyncComponent
在 Vue 3 中,异步组件必须使用defineAsyncComponent进行显式声明。
示例
<template> <div> <h1>主页面</h1> <button @click="showChart = true">加载并显示报表</button> <AsyncChart v-if="showChart" /> </div> </template> <script setup lang="ts"> import { ref, defineAsyncComponent } from 'vue'; const showChart = ref<boolean>(false); // 显式定义异步组件 const AsyncChart = defineAsyncComponent(() => import('@/components/BigChart.vue') ); // 高级配置(可选):带加载状态 const AsyncComponentWithConfig = defineAsyncComponent({ loader: () => import('./components/MyComponent.vue'), loadingComponent: LoadingComponent, // 加载过程中显示的组件 errorComponent: ErrorComponent, // 加载失败时显示的组件 delay: 200, // 展示加载组件前的延迟时间 timeout: 3000 // 超时时间 }); </script>2. Vue 2 中直接使用import函数声明异步组件
export default { components: { // 定义一个异步组件 'MyLazyComponent': () => import('./components/MyLazyComponent.vue') } }三、 底层原理与分包策略
1. 打包工具的配合
当你使用import()时:
- Vite/Rollup:会自动将该组件及其依赖提取到一个独立的
.js文件中。 - Webpack:会生成一个
chunk,你可以通过“魔法注释”自定义 chunk 的名称:
const About = () => import(/* webpackChunkName: "about-group" */ './About.vue')四、 总结
- 首屏优化:建议首页(Home)使用静态导入,而其他非核心路径、非首屏展示的弹窗/插件全部使用懒加载。
- 用户体验:使用异步组件时,建议配合
loadingComponent,避免加载过程中组件区域出现突兀的空白 。
原文: https://juejin.cn/post/76016061