HomeBlogPerformance
PERFORMANCE

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.

UIChart.com·June 1, 2025·6 min read

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
#performance#react#optimization#recharts#tips