331
docs/NAIVE_UI_OPTIMIZATION.md
Normal file
331
docs/NAIVE_UI_OPTIMIZATION.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# Naive UI 组件颗粒度拆分优化指南
|
||||
|
||||
本文档详细介绍了如何对 Naive UI 进行组件颗粒度的拆分,以优化应用的性能和加载速度。
|
||||
|
||||
## 📋 目录
|
||||
|
||||
1. [优化概述](#优化概述)
|
||||
2. [已实施的优化](#已实施的优化)
|
||||
3. [使用方法](#使用方法)
|
||||
4. [性能监控](#性能监控)
|
||||
5. [最佳实践](#最佳实践)
|
||||
6. [故障排除](#故障排除)
|
||||
|
||||
## 🎯 优化概述
|
||||
|
||||
### 主要优化目标
|
||||
|
||||
- **减少初始包大小**: 通过按需加载减少首次加载时间
|
||||
- **提高缓存效率**: 将组件按功能模块分组,提高缓存命中率
|
||||
- **优化用户体验**: 根据页面类型预加载相关组件
|
||||
- **降低内存占用**: 避免加载不必要的组件代码
|
||||
|
||||
### 优化策略
|
||||
|
||||
1. **代码分割**: 将 Naive UI 组件按功能分组打包
|
||||
2. **懒加载**: 按需加载组件,避免一次性加载所有组件
|
||||
3. **预加载**: 根据路由智能预加载相关组件
|
||||
4. **Tree Shaking**: 确保只打包实际使用的组件代码
|
||||
|
||||
## ✅ 已实施的优化
|
||||
|
||||
### 1. 精细化代码分割
|
||||
|
||||
在 `rsbuild.config.ts` 中配置了以下分割策略:
|
||||
|
||||
```typescript
|
||||
// 按功能模块分割 Naive UI 组件
|
||||
cacheGroups: {
|
||||
"naive-ui-core": { // 核心组件(必需)
|
||||
test: /config-provider|theme|locale|loading-bar|message|notification|dialog/,
|
||||
priority: 30
|
||||
},
|
||||
"naive-ui-form": { // 表单组件
|
||||
test: /form|input|select|date-picker|time-picker|upload/,
|
||||
priority: 25
|
||||
},
|
||||
"naive-ui-data": { // 数据展示组件
|
||||
test: /table|data-table|list|tree|transfer|pagination/,
|
||||
priority: 25
|
||||
},
|
||||
"naive-ui-layout": { // 布局组件
|
||||
test: /layout|grid|space|divider|card|collapse/,
|
||||
priority: 25
|
||||
},
|
||||
"naive-ui-feedback": { // 反馈组件
|
||||
test: /modal|drawer|popover|tooltip|spin|skeleton/,
|
||||
priority: 25
|
||||
},
|
||||
"naive-ui-navigation": { // 导航组件
|
||||
test: /menu|dropdown|tabs|steps|breadcrumb/,
|
||||
priority: 25
|
||||
},
|
||||
"naive-ui-display": { // 显示组件
|
||||
test: /tag|badge|avatar|image|carousel|calendar/,
|
||||
priority: 25
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 组件懒加载系统
|
||||
|
||||
创建了 `src/utils/lazy-components.ts` 提供:
|
||||
|
||||
- **懒加载组件工厂**: 创建按需加载的组件
|
||||
- **预加载策略**: 根据页面类型预加载相关组件
|
||||
- **路由守卫集成**: 在路由切换时自动预加载
|
||||
|
||||
### 3. 智能预加载
|
||||
|
||||
根据不同页面类型预加载相应组件:
|
||||
|
||||
- **首页**: 预加载核心组件(Button, Input, Card, Space, Flex)
|
||||
- **列表页**: 预加载数据组件(DataTable, Pagination, Tag, Badge)
|
||||
- **编辑页**: 预加载表单组件(Form, FormItem, Select, DatePicker, Upload)
|
||||
- **管理员页面**: 预加载管理组件(Modal, Drawer, Popconfirm, Editor)
|
||||
|
||||
### 4. 包体积分析工具
|
||||
|
||||
提供了 `scripts/analyze-bundle.js` 用于:
|
||||
|
||||
- 分析打包结果
|
||||
- 识别大文件和重复代码
|
||||
- 生成优化建议
|
||||
- 监控 Naive UI 组件占比
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 运行包体积分析
|
||||
|
||||
```bash
|
||||
# 分析当前构建
|
||||
npm run analyze
|
||||
|
||||
# 构建并分析
|
||||
npm run build:analyze
|
||||
```
|
||||
|
||||
### 使用懒加载组件
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { LazyComponents } from '~/utils/lazy-components'
|
||||
|
||||
// 使用懒加载的数据表格
|
||||
const LazyDataTable = LazyComponents.DataTable()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<LazyDataTable :data="tableData" :columns="columns" />
|
||||
</template>
|
||||
```
|
||||
|
||||
### 手动预加载组件
|
||||
|
||||
```typescript
|
||||
import { PreloadStrategies } from '~/utils/lazy-components'
|
||||
|
||||
// 在需要时预加载表单组件
|
||||
await PreloadStrategies.preloadForm()
|
||||
```
|
||||
|
||||
## 📊 性能监控
|
||||
|
||||
### 关键指标
|
||||
|
||||
监控以下指标来评估优化效果:
|
||||
|
||||
1. **首次内容绘制 (FCP)**: 应该有显著提升
|
||||
2. **最大内容绘制 (LCP)**: 页面主要内容加载时间
|
||||
3. **首次输入延迟 (FID)**: 用户交互响应时间
|
||||
4. **累积布局偏移 (CLS)**: 页面稳定性
|
||||
|
||||
### 使用分析工具
|
||||
|
||||
```bash
|
||||
# 查看详细的包分析报告
|
||||
npm run build:analyze
|
||||
|
||||
# 检查生成的分析文件
|
||||
cat bundle-analysis.json
|
||||
```
|
||||
|
||||
### 浏览器开发者工具
|
||||
|
||||
1. 打开 Network 面板
|
||||
2. 刷新页面观察资源加载
|
||||
3. 查看 Coverage 面板了解代码使用率
|
||||
4. 使用 Lighthouse 进行性能评估
|
||||
|
||||
## 💡 最佳实践
|
||||
|
||||
### 1. 组件选择原则
|
||||
|
||||
- **优先使用轻量级组件**: 如 `n-button` 而不是 `n-popconfirm`
|
||||
- **按需导入具体组件**: 避免导入整个 Naive UI 库
|
||||
- **合理使用复合组件**: 在需要时才使用复杂的组合组件
|
||||
|
||||
### 2. 路由级优化
|
||||
|
||||
```typescript
|
||||
// ✅ 好的做法:按功能模块组织路由
|
||||
const routes = [
|
||||
{
|
||||
path: '/admin',
|
||||
component: () => import('~/layouts/AdminLayout.vue'), // 管理员布局
|
||||
children: [
|
||||
{
|
||||
path: 'users',
|
||||
component: () => import('~/admin/UserManagement.vue') // 用户管理
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// ❌ 避免:在一个组件中使用过多不同类型的组件
|
||||
```
|
||||
|
||||
### 3. 组件导入策略
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
// ✅ 好的做法:明确导入需要的组件
|
||||
import { NButton, NInput, NForm } from 'naive-ui'
|
||||
|
||||
// ✅ 或者使用自动导入(已配置)
|
||||
// 组件会自动按需导入
|
||||
|
||||
// ❌ 避免:导入整个库
|
||||
// import * as naive from 'naive-ui'
|
||||
</script>
|
||||
```
|
||||
|
||||
### 4. 样式优化
|
||||
|
||||
```css
|
||||
/* ✅ 好的做法:使用 CSS 变量自定义主题 */
|
||||
:root {
|
||||
--n-color-primary: #007bff;
|
||||
--n-color-primary-hover: #0056b3;
|
||||
}
|
||||
|
||||
/* ❌ 避免:重写大量组件样式 */
|
||||
```
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 组件未正确加载
|
||||
|
||||
**症状**: 页面显示组件未定义错误
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 确保在 rsbuild.config.ts 中正确配置了 NaiveUiResolver
|
||||
Components({
|
||||
resolvers: [NaiveUiResolver()],
|
||||
dts: "./src/components.d.ts",
|
||||
})
|
||||
```
|
||||
|
||||
#### 2. 样式丢失
|
||||
|
||||
**症状**: 组件显示但样式不正确
|
||||
|
||||
**解决方案**:
|
||||
```vue
|
||||
<!-- 确保在 App.vue 中正确配置了 ConfigProvider -->
|
||||
<template>
|
||||
<n-config-provider :theme="isDark ? darkTheme : null">
|
||||
<router-view />
|
||||
</n-config-provider>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 3. 打包体积过大
|
||||
|
||||
**症状**: 构建后的文件仍然很大
|
||||
|
||||
**解决方案**:
|
||||
1. 运行 `npm run analyze` 查看详细分析
|
||||
2. 检查是否有重复导入的组件
|
||||
3. 确认 tree-shaking 正常工作
|
||||
|
||||
#### 4. 懒加载组件闪烁
|
||||
|
||||
**症状**: 组件加载时出现明显的闪烁
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 调整懒加载配置,增加加载组件
|
||||
const LazyComponent = createLazyComponent(
|
||||
() => import('naive-ui').then(m => ({ default: m.NDataTable })),
|
||||
{
|
||||
loadingComponent: LoadingSpinner, // 添加加载组件
|
||||
delay: 200 // 调整延迟时间
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 性能调试
|
||||
|
||||
#### 1. 使用 Chrome DevTools
|
||||
|
||||
```javascript
|
||||
// 在控制台中运行,查看组件加载情况
|
||||
performance.mark('component-load-start')
|
||||
// ... 组件加载代码 ...
|
||||
performance.mark('component-load-end')
|
||||
performance.measure('component-load', 'component-load-start', 'component-load-end')
|
||||
```
|
||||
|
||||
#### 2. 使用 Vue DevTools
|
||||
|
||||
安装 Vue DevTools 扩展,查看组件树和性能信息。
|
||||
|
||||
#### 3. 网络分析
|
||||
|
||||
```bash
|
||||
# 使用 webpack-bundle-analyzer 分析包结构
|
||||
npm install --save-dev webpack-bundle-analyzer
|
||||
```
|
||||
|
||||
## 📈 预期效果
|
||||
|
||||
实施这些优化后,你应该能看到:
|
||||
|
||||
- **首次加载时间减少 30-50%**
|
||||
- **Naive UI 相关代码分割为 6-8 个独立的 chunk**
|
||||
- **按需加载减少初始包体积 20-40%**
|
||||
- **页面切换时的组件加载更加平滑**
|
||||
- **更好的缓存命中率和更新策略**
|
||||
|
||||
## 🔄 持续优化
|
||||
|
||||
### 定期检查
|
||||
|
||||
1. **每周运行一次包分析**: `npm run build:analyze`
|
||||
2. **监控核心 Web 指标**: 使用 Google PageSpeed Insights
|
||||
3. **用户体验测试**: 在不同网络条件下测试加载性能
|
||||
4. **依赖更新**: 定期更新 Naive UI 和相关依赖
|
||||
|
||||
### 优化迭代
|
||||
|
||||
1. 根据实际使用情况调整预加载策略
|
||||
2. 监控新增组件的使用频率,调整分组策略
|
||||
3. 根据用户反馈优化加载体验
|
||||
4. 持续关注 Naive UI 的新特性和优化建议
|
||||
|
||||
---
|
||||
|
||||
## 📞 支持
|
||||
|
||||
如果在实施过程中遇到问题,可以:
|
||||
|
||||
1. 查看 [Naive UI 官方文档](https://www.naiveui.com/)
|
||||
2. 检查 `bundle-analysis.json` 分析报告
|
||||
3. 使用浏览器开发者工具进行调试
|
||||
4. 参考本项目的具体实现代码
|
||||
|
||||
记住,性能优化是一个持续的过程,需要根据实际使用情况不断调整和改进。
|
||||
Reference in New Issue
Block a user