Skip to content
+

Charts - Performance

Learn how to keep charts fast and responsive when rendering large datasets.

The performance of a chart can be decomposed in multiple factors: The time for computations, the React re-renders time, the time for the DOM update. This page describes the most impactful options you can use to keep rendering smooth.

Provide stable references

Charts derive a lot of state from their axes/series and recompute it whenever the relevant prop changes by reference. Passing a new array or object on every render forces this work to run again and triggers extra re-renders, even when the data itself hasn't changed.

The following props benefit from a stable reference:

  • series
  • xAxis, yAxis, and zAxis
  • dataset
  • margin
  • colors

When the value never changes, define it outside the component so the same reference is reused across renders:

// Defined once, outside the component.
const xAxis = [{ scaleType: 'band', data: ['A', 'B', 'C'] }];

function MyChart() {
  return <BarChart xAxis={xAxis} series={series} height={300} />;
}

When the value depends on props or state, wrap it in useMemo so it is only recomputed when its inputs change:

function MyChart({ data }) {
  const series = React.useMemo(() => [{ data }], [data]);

  return <LineChart series={series} height={300} />;
}

Skip animations

Animations are convenient for small charts, but they require updating the DOM on every frame. With many data points, this work multiplies.

Set the skipAnimation prop to render the final state directly, without transitions:

<LineChart series={series} skipAnimation />

Remove marks from line charts

If you set showMark to true for line series, a mark element is render for every data point. For a series with thousands of points, this adds thousands of DOM nodes that can impact performances.

Either disable marks, or reduce their number

// One mark per 100 values.
showMark: ({ index }) => index % 100 === 0;
// Only a mark at the end of the series.
showMark: 'end';
// Only a mark at the beginning of the series.
showMark: 'start';

See Line charts—Optimization for more details.

Use a more efficient renderer

By default, each item is drawn as its own SVG element—a <rect> per bar, a <circle> per scatter point. This is flexible but doesn't scale well: the number of DOM nodes grows with the number of data points.

Bar and scatter charts accept a renderer prop to switch to a more efficient drawing strategy:

  • 'svg-single' (default): renders every item in its own SVG element.
  • 'svg-batch': batches all items into a few <path> elements, which dramatically reduces the DOM node count for large datasets.
<BarChart series={series} renderer="svg-batch" />

The batch renderer comes with some trade-offs, such as not being able to style individual items with CSS. See the dedicated sections for the full list of limitations and live demos:

WebGL renderer

For the largest datasets, BarChartPremium, ScatterChartPremium, and HeatmapPremium support a 'webgl' renderer that draws items into a single <canvas> element, using GPU. This trades item-level interactivity for the ability to render hundreds of thousands of points.

<ScatterChartPremium series={series} renderer="webgl" />

See Bar charts—WebGL renderer, Scatter charts—WebGL renderer, and Heatmap—WebGL renderer for details and demos.