第一步:诊断(必须做)
按照分析工具
Base
pnpm add -D rollup-plugin-visualizer
or
yarn add -D rollup-plugin-visualizer
TypeScript
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'
plugins: [
visualizer({
open: true,
gzipSize: true,
brotliSize: true
})
]
运行
Base
pnpm build
or
yarn build
重点观察
在分析页里重点看
| 关注点 | 看什么 |
|---|---|
| 那个chunk最大 | 首屏是否>500kb |
| Inported by | 谁引用了它 |
| 重依赖 | 是否多个chunk重复打包 |
| 大JSON图/图标 | 是否被主入口引用 |
常见"元凶"
- 第三方UI库全量引入(如 ant-design-vue/element plus)
- lodash 全量
- moment
- echarts
- icon大数据文件
- 地图geojson
- 误import整个utils目录
第二步:合理分包(manualChunks)
这是最核心的优化点
TypeScript
build: {
rollupOptions: {
output: {
manualChunks(id) {
// 1️⃣ 第三方库分离
if (id.includes('node_modules')) {
if (id.includes('ant-design-vue'))
return 'antd-vendor'
if (id.includes('vue'))
return 'vue-core'
return 'vendor'
}
// 2️⃣ 业务页面自动分包
if (id.includes('src/views/')) {
const parts = id.split('/')
const index = parts.indexOf('views')
const folderName = parts[index + 1]
return `view-${folderName}`
}
}
}
}
}
优化目标
| 包类型 | 目标 |
|---|---|
| 主入口index | <200kb |
| vendor | 可缓存 |
| 每个view | 按需加载 |
第三步:巨型静态数据处理
错误示范
TypeScript
// main.ts
import icons from './all-icons.js' // ❌ 500kB 直接进主包
正确做法(动态加载)
TypeScript
const loadIcons = () => import('./all-icons.js')
规则
| 文件大小 | 处理方式 |
|---|---|
| >100kB | 必须动态import |
| >300kb | 拆分 or cdn |
| >1MB | 禁止进主包 |
第四步:资源CDN化
1. vite base 指向 CDN
TypeScript
export default defineConfig({
base: process.env.NODE_ENV === 'production'
? 'https://cdn.xxx.com/'
: '/'
})
2. 图片/字体策略
- .woff2>100kB 上传CDN
- 大背景图禁止进JS
- 不要base64大图
3. 巨型JS文件CDN化 例如:
- icon库
- geojson
- 富文本编辑器扩展 直接
html
<script src="https://cdn.xxx.com/icons.js"></script>
第五步:PWA检查
如果使用
代码
vite-plugin-pwa
必须检查:
TypeScript
workbox: {
globPatterns: ['**/*.{js,css,html}']
}
风险点
- index.html被precache
- index.js 过大
- 每次发布强制用户下载大包
建议
- 只precache必要资源
- 避免缓存大业务chunk
- 首屏尽量轻量
进阶补充
1. 开启esbuild压缩
TypeScript
build: {
minify: 'esbuild'
}
2. 开启tree shaking 优化
TypeScript
optimizeDeps: {
include: []
}
不要乱include
3. 路由懒加载必须写对
TypeScript
{
path: '/home',
component: () => import('@/views/home/index.vue')
}
禁止
TypeScript
import Home from '@/views/home/index.vue'