Performance
A multi-layer Canvas2D pipeline repaints only dirty layers each frame. Two things keep large data fast.
LTTB downsampling
Line and area charts automatically downsample the visible range to ~2 points per pixel with Largest-Triangle-Three-Buckets when there are far more bars than pixels — the line stays visually identical while drawing dozens of times fewer points. A no-op at normal zoom. The algorithm is exported for your own use:
import { lttbDownsample } from '@tradecanvas/chart'
// indices preserving the shape of a 100k series, reduced to 1600 points
const idx = lttbDownsample(series.length, 1600, (i) => series[i].close) Benchmark
Downsampling throughput (pnpm bench, single core):
| Visible points → 1600 | Time / frame | Throughput |
|---|---|---|
| 10,000 | ~0.025 ms | 39,600 / s |
| 100,000 | ~0.32 ms | 3,100 / s |
| 1,000,000 | ~2.6 ms | 380 / s |
A 100k-bar line chart downsamples in ~0.3 ms — well inside a 16.6 ms frame budget — then draws ~62× fewer points (100k → 1600).
Visible-range rendering
Every renderer iterates only the bars currently in view, never the whole series.