# 振动报表性能优化方案

## 目标

针对“海量测点 + 高频刷新 + 多图表并行渲染”的位移专属看板，目标不是单点堆优化，而是把压力拆到：

1. 浏览器主线程
2. Vue 响应式系统
3. ECharts 渲染层
4. HTTP 请求层
5. 后端聚合与 SQL 分表层

---

## 一、浏览器渲染极致优化

### 1. 限制单图可见点数

- 单条趋势图建议控制在 `800 ~ 1500` 点以内。
- 超过阈值后按时间桶抽样，不直接把原始全部点位塞给 ECharts。
- 当前看板主要依赖后端 `VibrationBoardServiceImpl` 的趋势压缩与 SQL 抽样能力，而不是前端本地明细降点。

### 2. 首屏只渲染当前页面图表

- 采用 `tempBoard` 同类目录方式拆成多页面。
- 每个菜单只挂一个页面，避免单页一次挂 8~10 个大图。
- 这样浏览器一次只承担当前页面所需图表，而不是整套报表一起首屏渲染。

### 3. 降低深层响应式开销

- 原始记录数组只在查询成功后整体替换，避免高频 `push/splice`。
- 图表配置不进全局 store，不参与不必要的跨组件依赖追踪。
- 大数组优先在查询后先处理好，再交给图表组件使用。

### 4. 避免同步重排抖动

- 图表容器高度固定，不使用内容撑开高度。
- 表格、树、图表分栏布局固定，减少重复回流。
- 尽量避免查询结果回来后再频繁切换条件渲染节点。

---

## 二、Vue 3.5 页面层压降策略

### 1. 多页面而不是超大单页

- `overview`
- `trend`
- `comparison`
- `quality`

每页只保留该报表必要组件，避免无关页面的 watcher 和计算属性在当前路由继续活着。

### 2. 共享查询逻辑，避免重复派生

- 设备树、查询参数和公共筛选状态统一放在 `useVibrationBoardQueryState.ts`
- 页面只拿派生结果，不重复各自再算一遍

### 3. 高频刷新节流

如果后续要加自动刷新，建议：

- 页面级自动刷新最短间隔 `>= 15s`
- 切后台标签页时暂停刷新
- 同一时刻仅保留一个未完成请求，新请求发起前取消旧请求

---

## 三、ECharts 渲染层压降策略

### 1. 趋势图降点

- 使用时间桶抽样
- 多设备对比时只展示 TopN 设备，建议 `6 ~ 12` 台

### 2. 图表类型选型收敛

优先使用：

- line
- bar
- gauge
- scatter

谨慎使用：

- 大规模 heatmap
- sankey
- tree/treemap
- 3D 图表

原因：

- 振动数据天然点数高，复杂图元越多，浏览器重绘成本越大。

### 3. 大数据图表配置建议

- 折线图：`showSymbol: false`
- 散点图：限制点数、限制标签数量
- 柱状图：设备数过多时只展示 TopN
- tooltip 避免做复杂 formatter 里的大循环

### 4. 图表实例复用

- 尽量复用同一图表实例，使用 `setOption`
- 不要在每次查询后 `dispose + init`
- 图表容器 resize 统一交给现有 `Chart.vue` 的 `ResizeObserver`

---

## 四、接口层与请求层压降策略

### 1. 一个页面一个接口口径

当前已按页面拆分接口：

- `/ems/report/vibrationBoard/overview`
- `/ems/report/vibrationBoard/trend`
- `/ems/report/vibrationBoard/comparison`
- `/ems/report/vibrationBoard/quality`
- `/ems/report/vibrationBoard/distribution`
- `/ems/report/vibrationBoard/anomaly`
- `/ems/report/vibrationBoard/advanced`

同时新增位移独立入口：

- `/ems/report/displacementBoard/*`

避免一个接口承担所有页面所需字段与计算。

### 2. 查询条件前置约束

- 默认最近 24 小时
- 时间跨度建议限制在 `<= 90 天`
- 多设备对比建议限制设备数量上限
- 自动刷新场景不允许大跨度历史查询

### 3. 请求去重与取消

后续建议在 request 层加入：

- 同页面同查询参数去重
- 新请求触发时取消旧请求
- 自动刷新与手动查询共享取消控制器

---

## 五、后端与 SQL 层性能降压

### 1. 分表路由先行

当前已经走 `RecordIotenvPartitionService`，只命中需要的 `record_iotenv_instant_yyyyMMdd` 分表。

### 2. 设备类型前置过滤

SQL 中直接使用：

- `ems_base_monitor_info.monitor_type = 10`

先缩小数据范围，再做抽样和排序。

### 3. 抽样在 SQL 层做

当前 `VibrationBoardMapper.xml` 已提供抽样查询：

- `selectSampledData`
- `selectQualitySampledData`

这是关键，因为如果把原始海量点全部回传前端再抽样，网络和浏览器都会先被打满。

### 4. 页面查询和导出查询分离

后续若增加导出，不要直接复用当前页面接口：

- 页面接口优先快
- 导出接口优先全

否则页面会被导出级数据量拖慢。

---

## 六、建议的容量阈值

### 前端单页建议阈值

- 单图折线点数：`<= 1200`
- 单图散点：`<= 3000`
- 单页图表数量：`<= 4`
- 单次多设备对比数量：`<= 12`

### 后端查询建议阈值

- 默认时间跨度：`24h`
- 高频自动刷新跨度：`1h ~ 6h`
- 历史趋势分析跨度：`<= 7d`
- 超长历史分析：强制抽样或分页聚合

---

## 七、后续增强建议

1. 为趋势页增加“后端桶聚合接口”，不再只依赖明细列表接口。
2. 为 comparison 页增加“后端排名接口”，前端只渲染最终排行。
3. 为 quality 页增加“后端质量统计接口”，把覆盖率、缺失率、延迟率都在 SQL/Service 层算完。
4. 若需要秒级自动刷新，建议单独开发“轻量实时页”，不要直接复用历史分析页。
