性能优化
TaroViz 基于 ECharts 优化,确保了良好的性能表现。但在处理大数据集或复杂图表时,仍然需要注意一些性能优化技巧。本指南将介绍如何优化 TaroViz 图表的性能。
1. 大数据集处理
1.1 数据采样
当数据量过大时,可以考虑对数据进行采样,只显示部分数据点:
typescript
// 数据采样函数
const sampleData = (data: number[], sampleSize: number) => {
if (data.length <= sampleSize) {
return data;
}
const step = Math.ceil(data.length / sampleSize);
return data.filter((_, index) => index % step === 0);
};
const BigDataExample = () => {
// 生成大数据集
const rawData = Array.from({ length: 10000 }, () => Math.floor(Math.random() * 1000));
// 采样后的数据
const sampledData = sampleData(rawData, 1000);
const option = {
// 配置项
series: [
{
data: sampledData,
type: 'line'
}
]
};
return (
<LineChart
chartId="big-data-chart"
option={option}
width="100%"
height={400}
/>
);
};1.2 数据过滤
根据用户需求,只显示相关的数据:
typescript
const FilteredDataExample = () => {
const [startDate, setStartDate] = useState('2024-01-01');
const [endDate, setEndDate] = useState('2024-01-31');
const [rawData, setRawData] = useState([]);
// 过滤数据
const filteredData = rawData.filter(item => {
return item.date >= startDate && item.date <= endDate;
});
const option = {
// 配置项
series: [
{
data: filteredData,
type: 'line'
}
]
};
return (
<LineChart
chartId="filtered-data-chart"
option={option}
width="100%"
height={400}
/>
);
};2. 渲染优化
2.1 减少重绘
避免频繁更新图表配置,尽量合并更新:
typescript
const OptimizedUpdateExample = () => {
const [option, setOption] = useState({
// 初始配置
});
// 优化的更新函数
const updateChart = (newData: number[]) => {
setOption(prev => ({
...prev,
series: [
{
...prev.series[0],
data: newData
}
]
}));
};
// 避免频繁调用 updateChart
useEffect(() => {
const interval = setInterval(() => {
// 生成新数据
const newData = Array.from({ length: 7 }, () => Math.floor(Math.random() * 100));
updateChart(newData);
}, 1000); // 每秒更新一次,避免过于频繁
return () => clearInterval(interval);
}, []);
return (
<LineChart
chartId="optimized-update-chart"
option={option}
width="100%"
height={400}
/>
);
};2.2 使用 canvas 渲染器
对于复杂图表,推荐使用 canvas 渲染器,性能更好:
typescript
const CanvasRendererExample = () => {
const option = {
// 复杂配置项
};
return (
<LineChart
chartId="canvas-chart"
option={option}
width="100%"
height={400}
renderer="canvas" // 使用 canvas 渲染器
/>
);
};2.3 关闭不必要的动画
对于大数据集,关闭动画可以提高渲染性能:
typescript
const NoAnimationExample = () => {
const option = {
animation: false, // 关闭全局动画
series: [
{
type: 'line',
data: Array.from({ length: 1000 }, () => Math.floor(Math.random() * 100)),
animation: false // 关闭系列动画
}
]
};
return (
<LineChart
chartId="no-animation-chart"
option={option}
width="100%"
height={400}
/>
);
};3. 内存管理
3.1 销毁图表实例
在组件卸载时,确保销毁图表实例,释放内存:
typescript
import React, { useEffect, useRef } from 'react';
import { LineChart, ChartRef } from '@agions/taroviz';
const MemoryManagementExample = () => {
const chartRef = useRef<ChartRef>(null);
const option = {
// 配置项
};
useEffect(() => {
return () => {
// 组件卸载时销毁图表实例
if (chartRef.current) {
chartRef.current.destroy();
}
};
}, []);
return (
<LineChart
ref={chartRef}
chartId="memory-chart"
option={option}
width="100%"
height={400}
/>
);
};3.2 避免内存泄漏
确保在组件卸载时清除所有定时器和事件监听器:
typescript
const MemoryLeakExample = () => {
const [option, setOption] = useState({
// 配置项
});
useEffect(() => {
const interval = setInterval(() => {
// 更新图表数据
setOption(prev => ({
...prev,
series: [
{
...prev.series[0],
data: Array.from({ length: 7 }, () => Math.floor(Math.random() * 100))
}
]
}));
}, 1000);
// 清除定时器
return () => clearInterval(interval);
}, []);
return (
<LineChart
chartId="memory-leak-chart"
option={option}
width="100%"
height={400}
/>
);
};4. 组件优化
4.1 使用 React.memo
对于频繁渲染的组件,使用 React.memo 优化:
typescript
import React, { useState } from 'react';
import { LineChart } from '@agions/taroviz';
// 使用 React.memo 包装图表组件
const MemoizedLineChart = React.memo(LineChart);
const OptimizedComponentExample = () => {
const [count, setCount] = useState(0);
const option = {
// 配置项
};
return (
<div>
<button onClick={() => setCount(prev => prev + 1)}>Increment</button>
<p>Count: {count}</p>
<MemoizedLineChart
chartId="memoized-chart"
option={option}
width="100%"
height={400}
/>
</div>
);
};4.2 延迟加载
对于非首屏图表,可以考虑延迟加载:
typescript
import React, { useState, useEffect } from 'react';
import { LineChart } from '@agions/taroviz';
const LazyLoadExample = () => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
// 模拟延迟加载
const timer = setTimeout(() => {
setIsVisible(true);
}, 1000);
return () => clearTimeout(timer);
}, []);
const option = {
// 配置项
};
return (
<div>
{isVisible && (
<LineChart
chartId="lazy-load-chart"
option={option}
width="100%"
height={400}
/>
)}
</div>
);
};5. 性能监控
5.1 使用 usePerformance Hook
TaroViz 提供了 usePerformance Hook,可以实时监控图表性能:
typescript
import React from 'react';
import { LineChart, usePerformance } from '@agions/taroviz';
const PerformanceMonitoringExample = () => {
const { metrics, isMonitoring, startMonitoring, stopMonitoring } = usePerformance({
autoStart: true,
interval: 1000
});
return (
<div>
<div>
<h3>性能指标</h3>
<p>帧率: {metrics.fps} FPS</p>
<p>渲染时间: {metrics.renderTime} ms</p>
<p>内存使用: {metrics.memoryUsage} MB</p>
</div>
<LineChart
chartId="performance-chart"
option={{ /* ... */ }}
width="100%"
height={400}
/>
<button onClick={isMonitoring ? stopMonitoring : startMonitoring}>
{isMonitoring ? '停止监控' : '开始监控'}
</button>
</div>
);
};5.2 使用 PerformanceAnalyzer
对于更详细的性能分析,可以使用 PerformanceAnalyzer 工具类:
typescript
import { PerformanceAnalyzer } from '@agions/taroviz';
const analyzer = new PerformanceAnalyzer();
analyzer.start();
// ... 图表操作 ...
const report = analyzer.getReport();
console.log('帧率:', report.fps, 'FPS');
console.log('渲染时间:', report.renderTime, 'ms');
analyzer.stop();5.3 监控渲染时间
监控图表的渲染时间,及时发现性能问题:
typescript
const RenderTimeExample = () => {
const [renderTime, setRenderTime] = useState(0);
const option = {
// 配置项
};
const handleRenderComplete = () => {
const endTime = performance.now();
const time = endTime - startTime;
setRenderTime(time);
console.log('图表渲染时间:', time, 'ms');
};
let startTime = performance.now();
return (
<div>
<p>渲染时间: {renderTime.toFixed(2)} ms</p>
<LineChart
chartId="render-time-chart"
option={option}
width="100%"
height={400}
onRenderComplete={handleRenderComplete}
/>
</div>
);
};6. 最佳实践
6.1 合理设置图表大小
根据实际需求设置图表大小,避免过大的图表:
typescript
const OptimizedSizeExample = () => {
const option = {
// 配置项
};
return (
<LineChart
chartId="optimized-size-chart"
option={option}
width="100%"
height={400} // 合理的高度
/>
);
};6.2 简化图表配置
对于复杂图表,尽量简化配置,减少不必要的元素:
typescript
const SimplifiedConfigExample = () => {
const option = {
// 简化的配置项
title: {
text: '简化配置示例'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'line',
// 简化系列配置
animation: false,
smooth: false,
areaStyle: null
}
]
};
return (
<LineChart
chartId="simplified-config-chart"
option={option}
width="100%"
height={400}
/>
);
};6.3 使用防抖和节流
对于频繁触发的事件,使用防抖和节流优化:
typescript
import { useDebounce, useThrottle } from '@agions/taroviz';
const DebouncedExample = () => {
const [value, setValue] = useState('');
const debouncedValue = useDebounce(value, 300);
// debouncedValue 会在 300ms 后更新
useEffect(() => {
// 执行耗时的搜索操作
performSearch(debouncedValue);
}, [debouncedValue]);
return <input value={value} onChange={e => setValue(e.target.value)} />;
};7. 跨平台性能优化
7.1 小程序平台优化
在小程序平台上,需要特别注意性能优化:
- 减少图表数量:每个页面尽量只使用一个图表
- 简化图表配置:减少不必要的动画和效果
- 合理设置图表大小:避免过大的图表
- 及时销毁图表实例:在页面卸载时销毁图表
- 使用懒加载:非首屏图表使用懒加载
7.2 H5 平台优化
在 H5 平台上,可以利用浏览器的性能特性:
- 使用 Web Workers 处理大数据
- 利用 requestAnimationFrame 优化动画
- 使用 Intersection Observer API 实现懒加载
- 利用浏览器缓存
8. 性能优化 Checklist
在开发过程中,可以使用以下 Checklist 来确保性能优化:
- [ ] 大数据集是否进行了采样或分页
- [ ] 是否关闭了不必要的动画
- [ ] 是否使用了合适的渲染器(canvas vs svg)
- [ ] 图表实例是否在组件卸载时正确销毁
- [ ] 是否清除了所有定时器和事件监听器
- [ ] 是否使用了 React.memo 优化频繁渲染的组件
- [ ] 是否对频繁触发的事件使用了防抖/节流
- [ ] 是否监控了性能指标(FPS、渲染时间)
下一步
继续阅读 跨平台开发 指南,了解如何在不同平台上使用 TaroViz。