性能监控系统完全指南
📋 概述
性能监控是保障ECharts应用稳定运行的关键。通过实时监控图表渲染时间、内存占用、FPS等指标,可以及时发现性能瓶颈和异常,优化用户体验。
核心价值
- 问题发现:及时发现性能退化
- 数据驱动:基于真实数据优化
- 用户洞察:了解实际使用体验
- 告警机制:异常情况及时通知
- 持续改进:建立性能基线和目标
🎯 监控指标
1. 核心指标
| 指标 | 说明 | 目标值 | 测量方法 |
|---|---|---|---|
| 初始化时间 | 图表首次渲染耗时 | <200ms | performance.now() |
| 更新耗时 | setOption执行时间 | <50ms | performance.now() |
| FPS | 帧率 | >55 | requestAnimationFrame |
| 内存占用 | 堆内存使用量 | <100MB | performance.memory |
| 错误率 | 图表渲染失败率 | <1% | try-catch统计 |
🔧 实现方案
1. 性能数据采集
typescript
// performance-monitor.ts
interface ChartPerformanceMetrics {
initTime: number; // 初始化时间
updateTime: number; // 更新时间
fps: number; // 帧率
memoryUsage: number; // 内存占用
errorCount: number; // 错误次数
}
class PerformanceMonitor {
private metrics: ChartPerformanceMetrics = {
initTime: 0,
updateTime: 0,
fps: 60,
memoryUsage: 0,
errorCount: 0
};
private frameCount = 0;
private lastTime = performance.now();
// 记录初始化时间
recordInit(startTime: number) {
this.metrics.initTime = performance.now() - startTime;
this.sendMetric('chart_init_time', this.metrics.initTime);
}
// 记录更新时间
recordUpdate(startTime: number) {
this.metrics.updateTime = performance.now() - startTime;
this.sendMetric('chart_update_time', this.metrics.updateTime);
}
// 监控FPS
startFPSMonitor() {
const measureFPS = () => {
this.frameCount++;
const currentTime = performance.now();
if (currentTime - this.lastTime >= 1000) {
this.metrics.fps = this.frameCount;
this.frameCount = 0;
this.lastTime = currentTime;
this.sendMetric('chart_fps', this.metrics.fps);
}
requestAnimationFrame(measureFPS);
};
requestAnimationFrame(measureFPS);
}
// 记录内存占用
recordMemory() {
if ('memory' in performance) {
const memory = (performance as any).memory;
this.metrics.memoryUsage = memory.usedJSHeapSize / 1024 / 1024; // MB
this.sendMetric('chart_memory_mb', this.metrics.memoryUsage);
}
}
// 记录错误
recordError(error: Error) {
this.metrics.errorCount++;
this.sendMetric('chart_error_count', this.metrics.errorCount);
// 上报错误详情
this.sendError({
message: error.message,
stack: error.stack,
timestamp: Date.now()
});
}
// 发送指标
private sendMetric(name: string, value: number) {
// 发送到监控平台
fetch('/api/metrics', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
value,
timestamp: Date.now()
})
}).catch(console.error);
}
// 发送错误
private sendError(error: any) {
fetch('/api/errors', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(error)
}).catch(console.error);
}
// 获取当前指标
getMetrics() {
return { ...this.metrics };
}
}
export default new PerformanceMonitor();1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
2. 集成到Hook
typescript
// useECharts.ts
import performanceMonitor from './performance-monitor';
export function useECharts(option: EChartsOption) {
useEffect(() => {
const startTime = performance.now();
try {
const chart = echarts.init(chartRef.current);
chart.setOption(option);
// 记录初始化时间
performanceMonitor.recordInit(startTime);
// 启动FPS监控
performanceMonitor.startFPSMonitor();
// 定期记录内存
setInterval(() => {
performanceMonitor.recordMemory();
}, 5000);
} catch (error) {
performanceMonitor.recordError(error as Error);
}
}, []);
// 监控更新性能
useEffect(() => {
if (chartInstance.current) {
const startTime = performance.now();
try {
chartInstance.current.setOption(option);
performanceMonitor.recordUpdate(startTime);
} catch (error) {
performanceMonitor.recordError(error as Error);
}
}
}, [option]);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
💡 监控平台集成
1. Sentry集成
typescript
import * as Sentry from '@sentry/react';
// 初始化
Sentry.init({
dsn: 'YOUR_DSN',
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1
});
// 上报错误
performanceMonitor.recordError = (error) => {
Sentry.captureException(error, {
tags: {
component: 'ECharts'
}
});
};
// 上报性能指标
performanceMonitor.sendMetric = (name, value) => {
Sentry.addBreadcrumb({
category: 'performance',
message: `${name}: ${value}`,
level: 'info'
});
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2. 自定义Dashboard
typescript
// 实时性能面板
function PerformanceDashboard() {
const [metrics, setMetrics] = useState(performanceMonitor.getMetrics());
useEffect(() => {
const interval = setInterval(() => {
setMetrics(performanceMonitor.getMetrics());
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<div className="perf-dashboard">
<div className="metric">
<label>初始化时间</label>
<span>{metrics.initTime.toFixed(0)}ms</span>
</div>
<div className="metric">
<label>FPS</label>
<span style={{ color: metrics.fps < 55 ? 'red' : 'green' }}>
{metrics.fps}
</span>
</div>
<div className="metric">
<label>内存占用</label>
<span>{metrics.memoryUsage.toFixed(2)}MB</span>
</div>
<div className="metric">
<label>错误次数</label>
<span style={{ color: metrics.errorCount > 0 ? 'red' : 'green' }}>
{metrics.errorCount}
</span>
</div>
</div>
);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
🎯 最佳实践
1. 性能预算
typescript
const PERFORMANCE_BUDGET = {
initTime: 200, // ms
updateTime: 50, // ms
fps: 55, // frames
memoryUsage: 100 // MB
};
// 检查是否超出预算
function checkBudget(metrics: ChartPerformanceMetrics) {
const violations = [];
if (metrics.initTime > PERFORMANCE_BUDGET.initTime) {
violations.push(`初始化时间超标: ${metrics.initTime}ms > ${PERFORMANCE_BUDGET.initTime}ms`);
}
if (metrics.fps < PERFORMANCE_BUDGET.fps) {
violations.push(`FPS低于标准: ${metrics.fps} < ${PERFORMANCE_BUDGET.fps}`);
}
if (violations.length > 0) {
console.warn('性能预算超标:', violations);
// 上报告警
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2. 采样上报
typescript
// 避免频繁上报
const SAMPLE_RATE = 0.1; // 10%采样
if (Math.random() < SAMPLE_RATE) {
this.sendMetric(name, value);
}1
2
3
4
5
6
2
3
4
5
6
📊 性能指标
| 监控项 | 开销 | 建议 |
|---|---|---|
| FPS监控 | <1% CPU | 始终开启 |
| 内存监控 | <5ms | 每5秒一次 |
| 错误捕获 | <1ms | 始终开启 |
| 指标上报 | 网络请求 | 采样或节流 |
🔗 相关链接
- 性能优化
- 错误处理
💎 总结
性能监控核心价值:
- ✅ 实时发现问题
- ✅ 数据驱动优化
- ✅ 用户体验保障
- ✅ 告警机制完善
关键原则:
- 全面监控:覆盖所有关键指标
- 低开销:监控本身不影响性能
- 智能采样:平衡精度和成本
- 及时告警:问题出现时立即通知
掌握性能监控,让应用更稳定!📊
