- Add archives/ directory for immutable external skill snapshots - Strict immutability rule: only README/CHANGELOG can be modified - First import: dev-pipeline-universal v1.0.0 (Hermes Agent) - Import dev-pipeline-universal into hermes-agent/skills/ with CHANGELOG - Update hermes-agent/publish/registry.json with imported skill - Rewrite meta-skills/create-hermes-agent-skill/ with full spec: - SKILL.md frontmatter fields and validator constraints - Recommended body structure (Overview → When to Use → Pitfalls → Verification) - Progressive disclosure (3-level loading) - 8 writing quality principles - Official reference skills from GitHub repo - Tool chain docs (skill_manage, /learn, skill_view) - Update README.md with archives/ in directory structure
95 lines
3.0 KiB
Markdown
95 lines
3.0 KiB
Markdown
# 前端构建优化(Vite 代码分割 + 路由懒加载)
|
||
|
||
> 适用于 Vue 3 + Vite 项目,Element Plus + ECharts 技术栈
|
||
|
||
## 问题
|
||
|
||
Vue 3 + Element Plus + ECharts 项目构建后,默认所有代码打包成一个 JS 文件(通常 2~3MB),首屏加载全量代码,严重影响首次加载速度。
|
||
|
||
## 优化方案
|
||
|
||
### 1. Vite `manualChunks` 拆包
|
||
|
||
在 `vite.config.js` 中配置 `build.rollupOptions.output.manualChunks`,将大体积第三方库拆为独立 chunk:
|
||
|
||
```js
|
||
// vite.config.js
|
||
export default defineConfig({
|
||
plugins: [vue()],
|
||
build: {
|
||
rollupOptions: {
|
||
output: {
|
||
manualChunks(id) {
|
||
// echarts 单独拆包(~1MB,仅访问图表页面时加载)
|
||
if (id.includes('node_modules/echarts')) {
|
||
return 'echarts'
|
||
}
|
||
// element-plus 单独拆包(~1MB,浏览器缓存)
|
||
if (id.includes('node_modules/element-plus')) {
|
||
return 'element-plus'
|
||
}
|
||
// vue 核心库单独拆包(~120KB)
|
||
if (id.includes('node_modules/vue') || id.includes('node_modules/@vue')) {
|
||
return 'vue-core'
|
||
}
|
||
},
|
||
},
|
||
},
|
||
chunkSizeWarningLimit: 500, // 提高告警阈值,避免拆包后仍有大 chunk 告警
|
||
},
|
||
})
|
||
```
|
||
|
||
**效果**:
|
||
| Chunk | 大小 | 加载时机 |
|
||
|:------|:----:|:--------|
|
||
| `vue-core` | ~120KB | 首屏 |
|
||
| `element-plus` | ~1MB | 首屏(浏览器缓存后不重复下载) |
|
||
| `echarts` | ~1MB | 仅访问图表页面时按需加载 |
|
||
| 各页面组件 | 2~15KB | 按需加载 |
|
||
|
||
### 2. 路由懒加载(动态 import)
|
||
|
||
将 `router/index.js` 中的静态 import 改为动态 `() => import(...)`:
|
||
|
||
```js
|
||
// ❌ 静态 import(全量加载)
|
||
import Dashboard from '../views/dashboard/Index.vue'
|
||
|
||
// ✅ 动态 import(按需加载)
|
||
const routes = [
|
||
{
|
||
path: '/dashboard',
|
||
component: () => import('../views/dashboard/Index.vue'),
|
||
},
|
||
]
|
||
```
|
||
|
||
Vite 会自动为每个动态 import 生成独立 chunk,文件名基于组件名(如 `Index-abc123.js`)。
|
||
|
||
### 3. 验证优化效果
|
||
|
||
```bash
|
||
# 构建前
|
||
ls -lh dist/assets/
|
||
# 输出:index-DoEo0YCm.js 2.3M ← 单文件
|
||
|
||
# 配置后构建
|
||
npm run build
|
||
ls -lh dist/assets/
|
||
# 输出:
|
||
# vue-core-BuIKajZo.js 119KB
|
||
# element-plus-C03w9GoR.js 1.0MB
|
||
# echarts-Bb6yjXMn.js 1.0MB
|
||
# Index-xxx.js 2~15KB(每个页面)
|
||
# ...
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
1. **manualChunks 函数**接收的是模块 ID(绝对路径),用 `id.includes()` 匹配 `node_modules` 中的包名
|
||
2. **路由懒加载**只在用户访问对应路由时才加载 chunk,首次访问某页面会有短暂加载延迟(通常 < 200ms)
|
||
3. **echarts 拆包后**,只有访问包含 ECharts 图表的页面(仪表盘、经营数据等)才会加载 echarts chunk
|
||
4. **chunkSizeWarningLimit** 建议设为 500KB,避免拆包后 element-plus/echarts 仍触发告警(它们确实很大)
|
||
5. **浏览器缓存**:element-plus 和 vue-core 拆为独立 chunk 后,只要版本不变,浏览器会缓存,后续页面访问不再下载
|