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 → 1600Time / frameThroughput
10,000~0.025 ms39,600 / s
100,000~0.32 ms3,100 / s
1,000,000~2.6 ms380 / 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.