Skip to content

[charts] POC: async scatter pipeline with skeleton#22366

Closed
JCQuintas wants to merge 1 commit into
mui:masterfrom
JCQuintas:perf-poc/worker-async-pipeline
Closed

[charts] POC: async scatter pipeline with skeleton#22366
JCQuintas wants to merge 1 commit into
mui:masterfrom
JCQuintas:perf-poc/worker-async-pipeline

Conversation

@JCQuintas

@JCQuintas JCQuintas commented May 7, 2026

Copy link
Copy Markdown
Member

Summary

POC for the Charts Performance — Data processing objective. Architecture spike for the async-pipeline approach (Option B in the findings doc).

Three pieces:

  • scatterWorker.ts — receives a Float64 (x, y) buffer + viewport metrics, computes the linear scale, and returns SVG path strings.
  • AsyncScatter.tsx — experimental React component that renders a skeleton until the worker returns, then swaps in <path> elements.
  • AsyncScatter.bench.tsx — pits the spike against ScatterChart at 100k and 1M.

Bench (chromium, 800x400)

Pts Async first paint (skeleton) Async full paint Sync ScatterChart paint
100k 6 ms 115 ms 1076 ms
1M 22 ms 1258 ms 12 599 ms (570x first)

Caveat

The component bypasses the lib's ChartProvider pipeline; the 10× full-paint speedup conflates worker offload AND no-pipeline. Production integration re-adds the pipeline tax. First-paint win (skeleton) survives regardless.

This POC validated the architecture; the proposed implementation is on feat/async-chart-pipeline (#22370). See charts-perf-data-processing.md.

Not for merge — POC reference, superseded by the async-pipeline plugin PR.

Architecture spike for KR1 (worker series prep). Three pieces:
- scatterWorker.ts: receives a Float64 (x,y) buffer + viewport metrics,
  computes the linear scale, and returns SVG path strings. Runs the full
  scatter pipeline (extremums + mapping + path build) off the main thread.
- AsyncScatter.tsx: experimental React component that renders a skeleton
  (border + "loading" placeholder) while the worker is busy, then swaps
  in the full <path> elements when the worker returns. Uses Transferable
  to ship the buffer (zero-copy out).
- AsyncScatter.bench.tsx: pits this against ScatterChart at 100k and 1M.

Bench at 800x400 (chromium):
- 100k async first paint (skeleton):     6ms
- 100k async full paint:               115ms
- 100k sync ScatterChart full paint:  1076ms  (9x slower)
- 1M  async first paint (skeleton):    22ms
- 1M  async full paint:              1258ms
- 1M  sync ScatterChart full paint: 12599ms  (10x full / 570x first paint)

Caveat: the comparison conflates two effects — bypassing the lib
ChartProvider pipeline AND running off the main thread. Production
integration would still wear the ChartProvider tax. Even so, the
skeleton + worker pattern is clearly the right shape for the
"responsive while loading" UX target.

Open questions for productionisation:
1. Public API: per-chart `processInWorker` flag? Auto-trigger above
   threshold? How to expose for users who already have Float64 data
   and want zero-copy?
2. Cancellation: when data prop changes mid-flight, terminate worker
   and start new (current POC does this on unmount only).
3. Worker bundling: Vite/Webpack handle `new Worker(new URL(...))` in
   apps; the lib needs to ship a worker entry that survives bundling.
4. Multi-chart pages: one worker per chart vs shared pool.
@JCQuintas JCQuintas added type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. scope: charts Changes related to the charts. labels May 7, 2026
@JCQuintas JCQuintas self-assigned this May 7, 2026
@code-infra-dashboard

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-22366--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@JCQuintas JCQuintas closed this Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: charts Changes related to the charts. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant