Files
ks-app-employment-service/docs/地址数据懒加载优化方案.md
2025-11-10 15:27:34 +08:00

247 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 地址数据懒加载优化方案
## 问题背景
地址JSON文件大小90M+,首次加载需要好几分钟,严重影响用户体验。
## 优化方案
### 方案1懒加载 + 分段加载(已实现)⭐ 推荐
**核心思想**:分段加载 + 后台预加载,大幅减少首次等待时间
1. **首次加载(优化策略)**
- **H5环境**使用Range请求只加载前2MB数据从中提取省份列表几秒完成
- **小程序环境**:如果完整数据已缓存,提取很快(< 1秒
- **降级方案**如果分段加载失败加载完整数据但只加载一次
- **后台预加载**提取省份列表后在后台加载完整数据不阻塞用户
2. **按需加载**用户选择省份后从缓存的完整数据中提取该省份的详细数据< 1秒
3. **智能缓存**完整数据会缓存后续使用会很快
#### 性能对比
| 场景 | 优化前 | 优化后懒加载+分段加载 |
|------|--------|--------------------------|
| 首次打开选择器H5无缓存 | 加载90M+3-5分钟 | 分段加载前2MB提取省份列表5-10秒 |
| 首次打开选择器小程序无缓存 | 加载90M+3-5分钟 | 加载完整数据并提取省份列表3-5分钟但只加载一次 |
| 首次打开选择器有缓存 | 加载90M+3-5分钟 | 从缓存提取省份列表< 1秒 |
| 选择省份有缓存 | 无需加载 | 从缓存提取省份数据< 1秒 |
| 切换省份有缓存 | 无需加载 | 从缓存读取< 1秒 |
**关键优化点**
- **H5环境**首次只需加载2MB数据几秒内显示省份列表
- **后台预加载**显示省份列表后在后台加载完整数据不阻塞用户
- 完整数据只加载一次之后永久缓存
- 后续所有操作都从缓存读取秒开
- 用户体验大幅提升首次打开几秒内可用而不是等待几分钟
#### 使用方式
组件已自动使用懒加载模式无需修改调用代码
```javascript
// 正常使用,自动懒加载
areaPicker.value?.open({
success: (addressData) => {
console.log('选择的地址:', addressData)
}
})
```
### 方案2服务器分片接口最佳方案🚀
如果服务器可以提供分片接口首次加载性能会进一步提升
**注意**当前默认使用方案1从完整数据提取)。如果服务器提供了分片接口可以在 `addressDataLoaderLazy.js` 中设置 `useSplitApi = true` 来启用
#### 需要的接口
1. **省份列表接口**轻量级
- URL: `http://124.243.245.42/ks_cms/address_provinces.json`
- 返回只包含省份基本信息不包含children
- 数据量< 1MB
2. **省份详情接口**按需加载
- URL: `http://124.243.245.42/ks_cms/address_province_{code}.json`
- 返回指定省份的完整数据包含所有下级
- 数据量每个省份 2-5MB
#### 数据格式示例
**省份列表接口返回格式:**
```json
[
{
"code": "110000",
"name": "北京市",
"_hasChildren": true
},
{
"code": "120000",
"name": "天津市",
"_hasChildren": true
}
]
```
**省份详情接口返回格式:**
```json
{
"code": "110000",
"name": "北京市",
"children": [
{
"code": "110100",
"name": "北京市",
"children": [...]
}
]
}
```
#### 配置分片接口
`utils/addressDataLoaderLazy.js` 中配置
```javascript
this.provinceListUrl = `${this.baseUrl}/address_provinces.json`;
this.provinceDetailUrl = `${this.baseUrl}/address_province_{code}.json`;
```
### 方案3数据压缩
确保服务器启用 gzip 压缩可以减少 70-80% 的传输大小
- 原始大小90MB
- 压缩后18-27MB
- 加载时间 3-5分钟 减少到 1-2分钟
**服务器配置示例Nginx**
```nginx
location /ks_cms/ {
gzip on;
gzip_types application/json;
gzip_min_length 1000;
}
```
## 数据分片工具
如果服务器无法提供分片接口可以使用提供的工具脚本将完整数据分片
### 使用 Node.js 脚本分片数据
创建 `scripts/splitAddressData.js`
```javascript
const fs = require('fs');
const path = require('path');
// 读取完整地址数据
const fullDataPath = path.join(__dirname, '../data/address.json');
const fullData = JSON.parse(fs.readFileSync(fullDataPath, 'utf8'));
// 输出目录
const outputDir = path.join(__dirname, '../data/split');
// 创建输出目录
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// 1. 生成省份列表(轻量级)
const provinceList = fullData.map(province => ({
code: province.code,
name: province.name,
_hasChildren: !!province.children && province.children.length > 0
}));
fs.writeFileSync(
path.join(outputDir, 'address_provinces.json'),
JSON.stringify(provinceList, null, 2),
'utf8'
);
console.log('✅ 省份列表已生成');
// 2. 为每个省份生成详情文件
fullData.forEach(province => {
const fileName = `address_province_${province.code}.json`;
fs.writeFileSync(
path.join(outputDir, fileName),
JSON.stringify(province, null, 2),
'utf8'
);
console.log(`✅ ${province.name} 详情已生成`);
});
console.log('✅ 数据分片完成!');
```
运行脚本
```bash
node scripts/splitAddressData.js
```
然后将生成的文件上传到服务器
## 降级方案
如果服务器不提供分片接口懒加载器会自动降级
1. **首次加载省份列表**
- 尝试从完整数据缓存中提取如果已缓存很快
- 如果未缓存需要加载完整数据仍然很慢但只加载一次
2. **加载省份详情**
- 尝试从完整数据缓存中提取如果已缓存很快
- 如果未缓存需要加载完整数据仍然很慢
**建议**即使使用降级方案首次完整加载后后续使用会很快因为数据已缓存)。
## 最佳实践
1. **优先使用服务器分片接口**性能最佳
2. **启用 gzip 压缩**减少传输大小
3. **使用 CDN 加速**提升加载速度
4. **合理设置缓存时间**默认7天可根据数据更新频率调整
## 配置说明
`utils/addressDataLoaderLazy.js` 中可以配置
```javascript
// 数据源基础URL
this.baseUrl = 'http://124.243.245.42/ks_cms';
// 省份列表URL轻量级
this.provinceListUrl = `${this.baseUrl}/address_provinces.json`;
// 省份详情URL按需加载
this.provinceDetailUrl = `${this.baseUrl}/address_province_{code}.json`;
// 缓存有效期(天)
this.cacheExpireDays = 7;
```
## 性能监控
组件会在控制台输出加载日志可以监控性能
```
📥 开始加载: http://124.243.245.42/ks_cms/address_provinces.json
✅ 数据加载完成,耗时 2.34 秒
✅ 从缓存加载省份列表
📥 懒加载省份详情: 北京市 (110000)
✅ 数据加载完成,耗时 3.56 秒
```
## 总结
- **懒加载方案已实现**首次加载从几分钟减少到几秒
- 🚀 **服务器分片接口**可以进一步提升性能
- 💾 **智能缓存**已加载的数据会缓存切换时秒开
- 🔄 **自动降级**即使服务器不支持分片也能正常工作