React Chart Performance Optimization — 7 Tips That Actually Work
Stop your charts from causing layout shifts and slow renders. These 7 practical techniques will make your React charts fast even with large datasets.
Why React Charts Get Slow
React charts re-render whenever their parent component re-renders. Since chart components are expensive to render (they recalculate all paths, scales, and axes), unnecessary re-renders are the #1 cause of slow dashboards.
Tip 1: Memoize Your Data
Never create chart data inline in JSX. Compute it with useMemo so it only recalculates when the underlying data changes:
// ❌ Bad — creates new array on every render
return <BarChart data={rawData.map(d => ({ ...d, value: d.value * 1.1 }))} />
// ✅ Good — only recalculates when rawData changes
const chartData = useMemo(() =>
rawData.map(d => ({ ...d, value: d.value * 1.1 })),
[rawData]
);
return <BarChart data={chartData} />
Tip 2: Disable Animation for Live Data
Recharts animates on every data change by default. For real-time charts this causes a constant animation loop:
<Line
dataKey="value"
isAnimationActive={false} // ← disable for live data
stroke="#00e5a0"
/>
Tip 3: Use Dynamic Imports
Chart libraries are large. Lazy-load them so they don't block the initial page render:
import dynamic from 'next/dynamic';
const RevenueChart = dynamic(
() => import('@/components/RevenueChart'),
{ ssr: false, loading: () => <ChartSkeleton /> }
);
Tip 4: Limit Data Points
SVG-based charts (Recharts) struggle beyond 1,000 data points. Downsample your data before passing to the chart:
function downsample(data: DataPoint[], maxPoints: number) {
if (data.length <= maxPoints) return data;
const step = Math.ceil(data.length / maxPoints);
return data.filter((_, i) => i % step === 0);
}
const chartData = useMemo(() => downsample(rawData, 200), [rawData]);
Tip 5: Wrap in React.memo
If a chart is in a frequently re-rendering parent, wrap it with React.memo:
const RevenueChart = React.memo(function RevenueChart({ data }: Props) {
return (
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data}>...</AreaChart>
</ResponsiveContainer>
);
});
// Now only re-renders when data prop changes (shallow comparison)
Tip 6: Set Fixed Heights to Avoid Layout Shift
Chart containers without a fixed height cause cumulative layout shift (CLS), hurting Core Web Vitals:
// ❌ Causes layout shift
<ResponsiveContainer width="100%" height="auto">
// ✅ Always use fixed pixel height
<ResponsiveContainer width="100%" height={320}>
Tip 7: Use Canvas for Very Large Datasets
If you need to render 10,000+ data points, switch to a canvas-based library. Chart.js renders on <canvas> and handles large datasets 10x faster than SVG-based Recharts.
Summary
- Memoize data with
useMemo - Disable animations for live/real-time charts
- Lazy-load chart components with
dynamic() - Downsample data to under 500 points for SVG charts
- Wrap stable charts in
React.memo - Always set fixed pixel heights
- Switch to Chart.js / canvas for 10K+ data points