Files
ks-app-employment-service/docs/地址数据懒加载优化方案.md

247 lines
7.3 KiB
Markdown
Raw Normal View History

2025-11-10 15:27:34 +08:00
# 地址数据懒加载优化方案
## 问题背景
地址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 秒
```
## 总结
-**懒加载方案已实现**:首次加载从几分钟减少到几秒
- 🚀 **服务器分片接口**:可以进一步提升性能
- 💾 **智能缓存**:已加载的数据会缓存,切换时秒开
- 🔄 **自动降级**:即使服务器不支持分片,也能正常工作