Performance, measured.
Real benchmarks. Real numbers. No marketing fluff.
Bundle Size Comparison
Gzipped transfer size. Smaller is better.
| Library | Bundle Size (gzip) | Chart Types | Tree-Shaking |
|---|---|---|---|
| Chart.ts | <15kb | 65+ | Full ESM |
| Chart.js | ~70kb | 8 | Partial |
| ECharts | ~300kb | 20+ | Limited |
| Recharts | ~45kb (+ D3 ~90kb) | 12 | No |
| Plotly.js | ~3.5MB | 40+ | No |
| Highcharts | ~80kb | 30+ | No |
| ApexCharts | ~125kb | 14 | No |
Rendering Performance
Time to first paint by data scale and renderer. Lower is better.
| Data Points | SVG | Canvas | WebGL |
|---|---|---|---|
| 100 | <1ms | <1ms | <1ms |
| 1,000 | 5ms | 2ms | 1ms |
| 10,000 | 45ms | 8ms | 3ms |
| 100,000 | N/A (use Canvas) | 80ms | 12ms |
| 1,000,000 | N/A | N/A (use WebGL) | 45ms |
Framework SSR Performance
Time to first byte for server-rendered charts.
<50ms
Next.js (React)
<50ms
Nuxt (Vue)
<50ms
SvelteKit
<50ms
SolidStart
Key Performance Facts
- Full library under 15kb gzipped with all 65+ chart types
- Single chart type import: 2-5kb gzipped
- Zero runtime dependencies in @chartts/core
- Automatic renderer switching at 10k (Canvas) and 100k (WebGL) thresholds
- requestAnimationFrame-throttled streaming for consistent 60fps
- LTTB (Largest Triangle Three Buckets) decimation for large datasets
- Lazy-loaded WebGL renderer: only loaded when needed
- Tree-shakeable ESM exports eliminate unused chart types from bundle
Benchmarks measured on M2 MacBook Pro, Chrome 124, averaged over 100 runs. Bundle sizes from bundlephobia.com and webpack-bundle-analyzer. SSR times measured with server-timing headers.