Skip to content

Production adoption path

Use vizcrush as the compute stage between data ingestion and rendering. The production path is deliberately small:

text
typed arrays → reduce/index with vizcrush → adapt the bounded result → render

Start with financial-timeseries for the full million-point flow, then choose the renderer adapter below.

1. Bound work to visible pixels

ts
import { minMaxLttb } from "@vizcrush/downsample";

export async function prepareLineSeries(
  x: Float64Array,
  y: Float64Array,
  cssWidth: number,
): Promise<{ x: Float64Array; y: Float64Array }> {
  if (x.length <= 2) return { x, y };
  const pixelRatio = globalThis.devicePixelRatio ?? 1;
  const target = Math.min(x.length, Math.max(2, Math.ceil(cssWidth * pixelRatio)));
  return minMaxLttb(x, y, target);
}

Keep the original typed arrays outside renderer state. Recompute when the viewport or source data changes, and pass only the reduced result to the chart.

2. Adapt after reduction

These adapters intentionally allocate ordinary objects only after vizcrush has bounded the point count.

Chart.js

ts
export function toChartJsPoints(result: { x: Float64Array; y: Float64Array }) {
  return Array.from(result.x, (x, index) => ({ x, y: result.y[index] }));
}

ECharts

ts
export function toEChartsPoints(result: { x: Float64Array; y: Float64Array }) {
  return Array.from(result.x, (x, index) => [x, result.y[index]] as const);
}

D3

ts
selection.attr("d", line(Array.from(result.x, (x, index) => [x, result.y[index]])));

Runnable implementations live in the Chart.js, React + ECharts, and Observable Plot examples.

3. Verify the backend in your deployment

Backend performance is engine-dependent. Use Backend Lab on representative hardware instead of copying an absolute benchmark from another runtime.

The repository’s packaged-browser workflow provides a stronger compatibility guarantee: it packs the same npm artifacts users install, installs them in a fresh fixture, bundles them with Vite, then executes forced WASM and JS calls with parity checks in Chromium, Firefox, and WebKit. Measurements are uploaded as workflow artifacts rather than marketed as universal numbers.

4. Inspect package cost

Check the registry artifact you are about to adopt:

bash
npm view @vizcrush/downsample version dist.unpackedSize dist.fileCount
npm pack --dry-run @vizcrush/downsample

Install only the primitive packages your application uses. There is no umbrella runtime package, so adopting downsampling does not pull in spatial, 3D, AI, React, or MCP code.

Production checklist

  • Keep raw data in typed arrays; allocate renderer objects after reduction.
  • Use a target derived from viewport width rather than a fixed global constant.
  • Warm the chosen operation before recording interactive latency.
  • Exercise the JS fallback in tests as well as WASM.
  • Move ingestion and preprocessing to a worker when parsing itself blocks the main thread.
  • Run npm audit/your normal supply-chain checks against the exact lockfile.
  • Measure on the browsers and devices your users actually run.

For worker transfer, see worker-pipeline. For density views, use deckgl-density-lod or bin2d() instead of rendering every scatter point.

Released under the MIT License.