When you're building a dashboard with a few dozen data points, any React charting library will work fine. Recharts, Victory, Nivo, visx, react-chartjs-2—they all render smooth charts at that scale. The performance differences only appear when you push the boundaries: thousands of data points, high-frequency updates, complex interactions, or multiple charts on the same page.
I've spent more time than I'd like optimizing React dashboards. The chart library you choose at the start can save you weeks of refactoring later. But raw benchmark numbers are often misleading. A library that wins a synthetic 10,000-point line chart test might fall over when you add tooltips, legends, and responsive containers.
So I set out to test the major React chart libraries under realistic conditions. Not just rendering a static chart, but updating data, handling interactions, and re-rendering within a larger React application. Here's what I found.
The libraries under test
This benchmark covers the five most popular React chart libraries in 2026:
- Recharts – The pragmatic default, widely used, declarative API.
- Victory – Feature-rich from Formidable, strong interactivity.
- Nivo – D3-powered, beautiful defaults, good SSR support.
- visx – Low-level building blocks from Airbnb, maximum flexibility.
- react-chartjs-2 – React wrapper for Chart.js, canvas-based rendering.
For each library, I built the same chart: a line chart with 10,000 data points, a bar chart with 500 bars, and a scatter plot with 5,000 points. I also tested re-render behavior by updating a single data point every second and toggling a prop that forced a full re-render. All tests ran in a controlled React 18 environment on a mid-range laptop.
The methodology (and why it matters)
Raw rendering speed is only part of the story. I measured:
- Initial render time – time from mount to visible chart.
- Re-render time – time to update after a data change.
- Animation smoothness – frame rate during a data transition.
- Memory usage – for large datasets.
- DOM node count – SVG vs canvas impact on the DOM.
These metrics reflect what users actually experience: a chart that takes 2 seconds to appear is a problem, but a chart that stutters when you hover over a point is equally frustrating. The DOM node count matters because a chart with 10,000 SVG elements can slow down the entire page, not just the chart itself.
If you've followed our React chart library comparison, you know that SVG-based libraries create one DOM node per data point, while canvas-based libraries draw to a single canvas element. That architectural difference drives most of the performance gaps.
The results: SVG vs canvas at scale
The biggest differentiator is whether the library renders to SVG or canvas.
SVG libraries (Recharts, Victory, Nivo, visx) create a DOM element for every data point. At 100 points, that's fine. At 1,000 points, you'll start to notice. At 10,000 points, the browser struggles with layout, hit-testing, and event handling. Recharts, Victory, and Nivo all showed significant lag when rendering 10,000-point charts. visx performed slightly better because it gives you lower-level control, but it's still SVG and hit the same wall.
Canvas libraries (react-chartjs-2) handle large datasets much better. Chart.js draws to a single canvas element, so there are no thousands of DOM nodes to manage. In my tests, react-chartjs-2 rendered a 10,000-point line chart in under 300ms, while Recharts took over 4 seconds and became unresponsive during interaction.
But canvas has its own tradeoffs. You lose CSS styling control. Accessibility requires additional work because canvas elements aren't semantic. And for small, interactive charts with lots of hover effects, SVG's DOM-based approach can actually feel more responsive because each element can have its own event handlers.
My general guideline: under 500 data points, SVG is fine. Between 500 and 2,000, SVG works but test carefully. Over 2,000, strongly consider canvas or a downsampling strategy.
Recharts: fast enough for dashboards, struggles with volume
Recharts is the most popular React charting library, and for good reason. It's easy to learn, well-documented, and handles common dashboard scenarios well. A line chart with 200 points rendered quickly, and tooltips were snappy.
Where Recharts showed weakness was large datasets and high-frequency updates. The render time for 10,000 points was over 4 seconds, and interaction (hovering over points) dropped the frame rate to single digits. Updating a single data point every second was fine, but a full data refresh with 5,000 points caused a visible lag.
Recharts also suffers from re-render cascades. If you wrap a chart in a component that re-renders frequently—like a dashboard with live data—the chart's internal elements re-render unnecessarily. If you've read our guide on preventing unnecessary re-renders in React, you know how to mitigate this with React.memo and stable props, but it adds complexity.
Verdict: Recharts is an excellent choice for typical dashboards with up to a few hundred points. For large datasets or real-time updates, you'll need optimization or a different library.
Victory: feature-rich but heavier
Victory impressed me with its interactivity. The Voronoi container for tooltips makes hovering near a line much easier, and the animation system is smooth. However, Victory's rich feature set comes at a cost. The bundle size is larger than Recharts, and the initial render time for the same charts was consistently slower.
For 10,000 points, Victory performed similarly to Recharts—slow and unresponsive during interaction. The animations, while beautiful, added overhead during data transitions. In my tests, a 500-bar chart with Victory took about 2 seconds to animate, while Recharts completed the same animation in under a second.
Victory's strength is complex interactive charts. If you need brushing, zooming, and tooltips that work well together, Victory is worth the performance tradeoff. For simple charts, it's overkill.
Verdict: Victory is the choice for interactive, complex visualizations where the extra features justify the performance cost. Not ideal for high-volume static charts.
Nivo: beautiful but not built for scale
Nivo produces stunning charts with minimal configuration. The default color palettes and typography make your dashboards look polished out of the box. It also has excellent server-side rendering support, which is great for Next.js.
But Nivo is not a performance workhorse. In my tests, Nivo's 10,000-point line chart took over 5 seconds to render and became completely unresponsive during interactions. The issue is that Nivo adds multiple layers (grid, axes, legends, labels) as separate SVG groups, increasing the DOM node count dramatically. A 10,000-point chart easily creates 30,000+ DOM nodes.
Nivo is also less flexible for optimization. Unlike Recharts, which lets you disable animations or use isAnimationActive={false}, Nivo's configuration doesn't expose as many performance knobs. If you need to render large datasets, you'll fight the library.
Verdict: Nivo is perfect for static charts with up to a few hundred points where appearance matters more than performance. Avoid it for large or heavily interactive datasets.
visx: the performance-aware choice (if you know D3)
visx is not a charting library—it's a set of low-level primitives. You build your own axes, scales, and shapes. This gives you complete control over rendering, and that control translates directly to performance.
With visx, I could optimize the 10,000-point line chart by using a single <path> element instead of individual points. The render time dropped to under 500ms, and interactions remained smooth. The catch? I had to know what I was doing. visx requires understanding D3 scales, SVG path generation, and React performance principles.
visx also has the smallest bundle size because you import only what you use. Tree-shaking is excellent. For teams with D3 experience, visx is the performance king. For teams that just want a chart, the learning curve is steep.
Verdict: visx is the best choice for performance-critical dashboards where you have the expertise to optimize. It's also great for custom visualizations that don't fit standard chart types.
react-chartjs-2: canvas performance without the headache
react-chartjs-2 wraps Chart.js, which uses canvas rendering. This gives it a massive performance advantage for large datasets. In my tests, react-chartjs-2 rendered a 10,000-point line chart in under 300ms—more than 10x faster than the SVG alternatives. Interaction was smooth, and memory usage was lower because there were no thousands of DOM nodes.
The downside is styling and accessibility. Canvas charts don't respond to CSS. If your design system uses CSS variables or theme classes, you'll need to configure Chart.js options programmatically. Accessibility is also harder—canvas requires fallback content and additional ARIA work.
Chart.js also has a different mental model. Instead of composing React components, you pass a data object and options. The React wrapper handles updates, but debugging Chart.js-specific issues requires understanding the underlying library.
Verdict: react-chartjs-2 is the best choice for large datasets and high-frequency updates. The canvas rendering sacrifices some flexibility but delivers performance where SVG libraries fail.
The re-render test: how libraries handle React's reactivity
A chart that renders quickly is only half the battle. How does it behave when the data changes? I tested each library by updating a single data point every 100ms for 10 seconds, then by triggering a full re-render of the parent component.
Recharts and Victory both struggled with frequent updates. They re-render the entire chart subtree when props change, even if only one data point changed. With React.memo and careful prop management, I could improve performance, but it required extra code.
Nivo handled updates slightly better because its data flow is more declarative. But it still re-rendered more than necessary.
visx shined here. Because you control the rendering, you can use useMemo and React.memo to isolate updates. My optimized visx chart only re-rendered the specific path that changed.
react-chartjs-2 performed well on updates because Chart.js handles the canvas updates internally. The React wrapper only re-renders when the data prop changes, and Chart.js efficiently updates the canvas without rebuilding the entire chart.
If you've implemented debounce and throttle patterns to reduce update frequency, you can pair those with any library to ease re-render pressure. But some libraries benefit more than others.
Bundle size and its impact on performance
Performance isn't just rendering. The size of the JavaScript bundle affects initial load time, especially on mobile. Here's how the libraries compare (gzipped, approximate):
- visx: ~12 KB (line chart only, tree-shaken)
- Recharts: ~43 KB
- Nivo: ~45 KB (line chart)
- react-chartjs-2 + Chart.js: ~58 KB
- Victory: ~60 KB (core + line chart)
These numbers matter on slow connections. A 60 KB chart library might add an extra 300ms to your initial load on 3G. If you're optimizing for performance, visx or a custom lightweight solution is compelling.
If you've read our React bundle size guide, you know that every kilobyte counts. Choosing the right chart library is part of that calculus.
The practical recommendation matrix
Here's how I'd choose based on your needs:
- Dashboard with < 500 points per chart, common chart types: Recharts. It's the easiest to use and maintain, and performance is fine.
- Complex interactive charts with brushing/zooming: Victory. The interactivity is worth the overhead.
- Beautiful static charts for presentations/reports: Nivo. The defaults save design time.
- Custom visualizations or performance-critical apps: visx. You'll need D3 skills, but the result is fast and flexible.
- Large datasets (> 2,000 points) or real-time updates: react-chartjs-2. Canvas rendering is the only viable option at this scale.
A real story: migrating a 50,000-point dashboard to canvas
I worked on a financial analytics platform that displayed 50,000 data points in a single chart. The original build used Recharts, and it was unusable. The page took 10 seconds to become interactive, and hovering over the chart froze the browser.
We tried optimizing Recharts—disabling animations, memoizing components, downsampling the data. It helped, but the chart was still sluggish. The fundamental problem was SVG's DOM overhead: 50,000 SVG elements is too many for any browser.
The solution was to switch to react-chartjs-2 (canvas). The same data rendered in under 500ms, and interactions were smooth. We lost some styling flexibility, but the performance gain was worth it. We also implemented a downsampling strategy that reduced the visible data points to 5,000, which further improved performance without sacrificing clarity.
The lesson: if you're dealing with genuinely large datasets, don't fight SVG. Use canvas or downsample. Your users won't notice the difference between 5,000 and 50,000 points, but they will notice a 10-second load time.
Wrapping up
React chart library performance is a spectrum. SVG libraries excel at flexibility and styling, canvas libraries excel at raw speed, and low-level tools like visx give you the control to optimize either approach. The right choice depends on your data volume, update frequency, and team expertise.
If you're picking a library for a new dashboard, start with Recharts for simplicity. If you know you'll have large datasets, skip straight to react-chartjs-2 or invest in visx. And always benchmark with your own data—the performance characteristics of a library can change dramatically based on chart type, data size, and interaction patterns.
For a deeper dive into the feature differences between these libraries, check out our React chart library comparison. And if you're optimizing a dashboard that feels slow, our guide on why modern websites feel slower will help you identify the real bottlenecks.
The best chart library is the one that lets you build fast, render fast, and sleep well at night knowing your dashboard won't freeze under load.
Need help optimizing your React dashboards for performance? Red Surge Technology builds data-heavy interfaces that stay responsive at scale. Get in touch to discuss your project.