Skip to content

Batched SVG measured performance

Latest verification: 19 October CPU/memory regression. Earlier measurements are historical.

M2 reference: Apple M1 Pro, MacBookPro18,3, 16 GiB RAM, macOS 26.4 (25E5207k). Chromium version and actual results are recorded in the adjacent JSON artifacts. Budgets below were fixed before production implementation. Single-item baseline is built from e8ec9af61 plus the existing uncommitted M1 changes.

Fixtures: deterministic 1,000 / 10,000 / 100,000 observations, one series for groupedColumn/groupedBar; one X/Y pair for scatter. No nulls in timing fixtures; correctness fixtures cover nulls separately. A 960×440 host resizes to 800×440. Three runs per combination, production ESM, headless Chromium, serial execution. Create includes model cloning/validation, geometry, DOM, and two animation frames; resize waits 100ms for ResizeObserver and two frames (100ms excluded). These are blocking paint latencies, not a claim of 60fps. Nearest-rank p95 of three runs is the maximum. Data construction/module loading precede the timer. GC before/after uses CDP; retained JS heap delta includes model/index/scene. CDP native embedder heap and backing storage are also reported. Process RSS is not measured.

Gate10k100k
Batched create and resize p95≤750ms≤5000ms
Pointer/keyboard inspection p95≤50ms≤100ms
Retained incremental JS heap≤128MiB≤512MiB

Default single-item 1k create/resize median may grow by no more than 20% plus a 15ms noise allowance relative to the recorded baseline. Structural gate: batched mark nodes grow by paint groups/chunks, never one per observation. Native memory and long-session memory are limitations of this local benchmark, not implied passed gates. No GPU, WebGL, Firefox, Safari, CI or deployed performance claim.

Run the opt-in chart-batched-svg-benchmark.spec.ts with CHART_BENCHMARK pointing to a JSON output path; set CHART_RENDERER_POLICY=batched-svg for batching.

CPU/memory optimization regression — 19 October 2026

Section titled “CPU/memory optimization regression — 19 October 2026”

All nine batched cases and all three default single-item SVG cases complete and pass the original M2 gates on the same final production graph as the latest WebGL CPU/memory results. The run used the original headless Chromium shell protocol, without Metal/8 GiB heap launch overrides, from 11:54:46 to 11:55:30 UTC inside the coordinated hold on other workspace builds/tests. It remains separate from the matched CPU/GPU full-Chromium stress protocol. Hardware and emitted-JavaScript hash are retained in raw batched results (packages/charts/docs/batched-svg-memory-optimized.json in the source repository) and raw 1k default SVG results (packages/charts/docs/batched-svg-memory-default.json in the source repository).

FamilyRowsCreate p95 msResize p95 msJS heap MiBPointer / keyboard p95 msNodes / batch pathsBudget
groupedColumn100077.929.24.50.1 / 0.656 / 1PASS
groupedColumn10000168.022.617.30.1 / 0.669 / 5PASS
groupedColumn1000001148.2364.7145.70.1 / 0.6109 / 49PASS
groupedBar100041.331.54.50.1 / 0.848 / 1PASS
groupedBar10000152.531.217.50.1 / 0.552 / 5PASS
groupedBar1000001333.5571.8149.20.2 / 0.596 / 49PASS
scatter100043.223.75.20.1 / 0.756 / 1PASS
scatter10000175.625.323.90.1 / 0.660 / 5PASS
scatter1000001910.1515.4214.00.1 / 0.5104 / 49PASS

1k default SVG comparison (median; limit = baseline × 1.2 + 15 ms):

FamilyBaseline create / resize msCurrent create / resize msGate
groupedColumn80.8 / 4.145.2 / 14.3PASS
groupedBar92.1 / 6.443.6 / 17.1PASS
scatter113.7 / 3.842.9 / 17.5PASS

The 1k default-SVG comparison passes its original median limit (baseline × 1.2 plus 15 ms). Its resize medians are higher than the original baseline, within that unchanged noise allowance; no resize improvement is claimed. The fixture includes two RAFs, without waiting for the full duration of any SVG entrance animation. It measures the recorded create/resize protocol, not completed animation latency. Functional transition tests separately verify committed geometry and exports. No observations or semantic inspection entries are dropped; 100k batched cases retain 49 batch paths rather than one mark node per datum.

Terminal window
node packages/charts/scripts/report-batched-svg.mjs packages/charts/docs/batched-svg-baseline.json packages/charts/docs/batched-svg-memory-optimized.json packages/charts/docs/batched-svg-memory-default.json --check

Historical integrated verification — 18 October 2026

Section titled “Historical integrated verification — 18 October 2026”

The final production graph, including optional GPU support and the private runtime snapshot optimization, passes all original M2 gates without changing the protocol, fixture or budgets. Runs started after package builds, workspace push hooks and compatibility jobs finished. Hardware and Chromium remain the same reference.

At 100k observations, groupedBar creation p95 is 2,171.5 ms and scatter 3,462.6 ms, versus current-build pre-optimization 5,155.1 / 7,862.4 ms. Scatter now has 1,537.4 ms headroom against its 5,000 ms creation gate. This remains a local measured result, not a guarantee on another host or dataset.

Raw final records: packages/charts/docs/batched-svg-integrated.json and batched-svg-integrated-default-svg.json in the source repository. Both identify source commit 462284b31 and the emitted-JavaScript SHA-256/hash protocol. Earlier optimization and initial implementation artifacts below remain historical.

FamilyRowsCreate p95 msResize p95 msJS heap MiBPointer / keyboard p95 msNodes / batch pathsBudget
groupedBar100050.517.05.00.1 / 0.448 / 1PASS
groupedBar10000242.921.523.90.1 / 0.552 / 5PASS
groupedBar1000002171.5783.8215.00.2 / 0.596 / 49PASS
groupedColumn100050.515.85.00.1 / 0.638 / 1PASS
groupedColumn10000220.3156.923.60.1 / 0.542 / 5PASS
groupedColumn1000002041.7574.6211.50.2 / 0.586 / 49PASS
scatter100056.020.25.80.1 / 0.656 / 1PASS
scatter10000332.615.331.50.1 / 0.560 / 5PASS
scatter1000003462.6783.1289.80.1 / 0.5104 / 49PASS

1k default SVG comparison (median; limit = baseline × 1.2 + 15 ms):

FamilyBaseline create / resize msCurrent create / resize msGate
groupedBar92.1 / 6.439.2 / 13.7PASS
groupedColumn80.8 / 4.138.1 / 11.2PASS
scatter113.7 / 3.847.1 / 10.9PASS

Recompute every gate, including the default-SVG medians:

Terminal window
node packages/charts/scripts/report-batched-svg.mjs packages/charts/docs/batched-svg-baseline.json packages/charts/docs/batched-svg-integrated.json packages/charts/docs/batched-svg-integrated-default-svg.json --check

Final compatibility: Charts 3,033 / 180 files; Pivot 4,069 / 326 files; 33 functional cases across Chromium, Firefox and WebKit. Package builds, public types and imports pass. These browser-engine checks establish functional compatibility, not measured Firefox/WebKit performance. Remote CI and deployment are recorded separately.

M3 closure regression verification — 18 October 2026

Section titled “M3 closure regression verification — 18 October 2026”

The shared parser/GPU resource changes retain every original M2 gate. All nine batched cases and three 1k default SVG cases pass on the same production graph as the GPU closure. Three unprofiled serial runs per case are retained in raw batched results (packages/charts/docs/batched-svg-m3-closure.json in the source repository) and raw default SVG results (packages/charts/docs/batched-svg-m3-closure-default-svg.json in the source repository). Hardware, browser, data, default-renderer baseline and budgets are unchanged.

FamilyRowsCreate p95 msResize p95 msJS heap MiBPointer / keyboard p95 msNodes / batch pathsBudget
groupedBar100046.920.05.10.1 / 0.548 / 1PASS
groupedBar10000206.312.424.40.1 / 0.552 / 5PASS
groupedBar1000001823.3615.4218.40.2 / 0.696 / 49PASS
groupedColumn100057.621.85.10.1 / 0.738 / 1PASS
groupedColumn10000185.6148.824.10.1 / 0.542 / 5PASS
groupedColumn1000001651.6511.5214.90.2 / 0.586 / 49PASS
scatter100050.618.56.00.1 / 0.756 / 1PASS
scatter10000270.117.431.90.1 / 0.660 / 5PASS
scatter1000002654.3484.3296.30.1 / 0.5104 / 49PASS

1k default SVG comparison (median; limit = baseline × 1.2 + 15 ms):

FamilyBaseline create / resize msCurrent create / resize msGate
groupedBar92.1 / 6.435.8 / 12.2PASS
groupedColumn80.8 / 4.134.2 / 14.3PASS
scatter113.7 / 3.840.4 / 14.4PASS