Performance guide

Design data loading and chart updates for large datasets.

Fast rendering starts before Canvas2D. Keep data columnar, transfer it once, avoid main-thread decoding, and let the chart render only the detail visible on screen.

LOD means level of detail: the renderer uses a screen-sized representation of large data and reveals finer detail as the user zooms. Start with worker auto-selection and the default LOD policy, then measure the real workload. Use the LOD calibration lab only before changing density, rebase ratio, or quantization.

  1. Show a small extrema-preserving preview when first-frame latency matters.
  2. Start network fetch and decoding in a dedicated data worker.
  3. Read only the required columns and ranges from a columnar format.
  4. Validate aligned lengths, finite ordered X, units, and declared gaps.
  5. Transfer typed columns to the chart renderer once.
  6. Terminate the data worker after transfer so it does not retain another copy.

For HTTP range reads, ensure the static host supports byte ranges and that intermediary caching preserves them. A correct full-download fallback can still be too expensive for mobile visitors.

Keep the initial bundle small

  • Dynamically import heavy data decoders and optional demos.
  • Mount only the chart currently visible or selected.
  • Do not ship multi-million-row showcase data to a landing page merely to prove the renderer can accept it.
  • Keep theme catalogs and secondary examples out of a protected first-frame path.
  • Prefer curated or adaptive examples on constrained devices and link to a full workbench.

Choose worker mode

Use renderMode: "auto" in general applications and measure the resolved mode. Main-thread mode is useful for tests and small static charts, but large interactive datasets should normally run in a worker.

Tune line presentation by workload

Most applications do not need custom LOD values.

lod.density is the primary fidelity/work control. Begin at 0.75. Increase it when local detail is visibly insufficient and frame time remains comfortable. Decrease it for multi-pass filled ranges, high device-pixel ratios, or browsers where Canvas2D fill cost dominates.

Representation smoothness depends on rebaseRatio and quantizationStep, not density alone. Finer values reduce individual texture changes but make hierarchy queries more frequent. Tune on real zoom gestures and compare steady-state frame time, query visits, presentation vertices, and visual stability.

Use setStatsCallback temporarily during development:

chart.setStatsCallback((stats) => {
  console.table({
    frame: stats.frameTime,
    mode: stats.presentationMode,
    vertices: stats.presentationVertices,
    visits: stats.presentationQueryVisits,
    ready: stats.lodReady,
  });
}, { intervalMs: 250 });

Disable the callback in production when the application does not consume telemetry.

Batch updates

  • Use bulk typed-array APIs when a complete batch already exists.
  • Use batch() for several synchronous imperative changes caused by one UI action.
  • Avoid constructing arrays or formatting strings inside per-frame callbacks.
  • Debounce application-side streaming rebuilds and ignore stale asynchronous results.

Preserve data meaning

Performance reduction must retain extrema and real gaps. Never pre-average a range envelope, connect missing intervals, or downsample each stacked-area input independently. For OHLCV, aggregate open-first, high-maximum, low-minimum, close-last, and summed volume over actual observations.