Skip to content

[docs-infra] Move type formatting into LS worker, parallelize validate#1317

Draft
JCQuintas wants to merge 6 commits intomasterfrom
jcquintas/perf-in-worker-format
Draft

[docs-infra] Move type formatting into LS worker, parallelize validate#1317
JCQuintas wants to merge 6 commits intomasterfrom
jcquintas/perf-in-worker-format

Conversation

@JCQuintas
Copy link
Copy Markdown
Member

@JCQuintas JCQuintas commented Apr 16, 2026

Summary

Performance changes that reduce validate --types runtime by 2.3–5.4× depending on available cores.

1. In-worker formatting (2.3× alone)

formatComponentData/formatHookData/formatFunctionData/formatClassData/formatRawData now run inside the LS worker thread (processTypes.ts) instead of the main validate-worker thread.

Why: The previous architecture shipped raw allTypes AST nodes across a Unix socket. Each chart component produced 45–50 MB of serialized data per file. With v8.serialize at ~2 MB/s effective throughput, IPC transport alone consumed 12–19 seconds per file — 98% of total runtime.

Now only the compact formatted TypesMeta[] (~500 KB) crosses the wire. Payload reduction: ~100×.

2. Parallel LS workers (additional 2.3×)

WorkerThreadTypesProcessor now runs processTypes directly in-thread instead of routing through a single shared socket server. Each validate worker gets its own TypeScript language service via the globalThis singleton in createOptimizedProgram. N workers = N parallel LS instances.

Worker count uses the existing availableParallelism() - 1 (unchanged from before).

3. Bug fixes

  • waitForSocketFile: Replaced fs.watch with polling on Unix. macOS FSEvents unreliably delivers filename in watch callbacks, causing 30s timeouts on every file.
  • removePrefixFromHighlightedNodes: Recurse into nested highlight <span> elements instead of breaking. Fixes type _ = prefix leaking into rendered output when the highlighter produces deeply nested token spans.

Benchmark (107 chart files, mui-x)

Config Wall CPU vs original
Original (1 LS + socket IPC) 1313 s 299%
In-worker format (1 worker) 573 s 104% 2.3×
N parallel LS workers (4 on test machine) 245 s 306% 5.4×

RAM: ~1 GB per LS worker instance.

Three performance changes that reduce validate --types runtime by ~5.4×:

1. In-worker formatting: formatComponentData/formatHookData/etc now run
   inside the LS worker thread (processTypes.ts) instead of the main
   validate-worker thread. This avoids serializing raw allTypes AST nodes
   (45–50 MB per chart component) across the Unix socket — only the compact
   formatted TypesMeta (~500 KB) crosses the wire.

2. Parallel LS workers: WorkerThreadTypesProcessor now runs processTypes
   directly in-thread instead of routing through a single shared socket
   server. Each validate worker gets its own TS language service via the
   globalThis singleton in createOptimizedProgram. N workers = N parallel
   LS instances. Worker count capped at 4 with staggered spawns to avoid
   Node's BuiltinLoader rwlock contention on macOS.

3. Bug fixes:
   - waitForSocketFile: replaced fs.watch with polling on Unix — macOS
     FSEvents unreliably delivers filename in watch callbacks, causing
     30s timeouts.
   - removePrefixFromHighlightedNodes: recurse into nested elements
     instead of breaking, fixing "type _ = " prefix leaking into output.

Benchmarked on 107 chart files (mui-x):
  Before:  1313s wall, 3479s CPU, 299% avg
  After:    245s wall,  705s CPU, 306% avg
@code-infra-dashboard
Copy link
Copy Markdown

code-infra-dashboard Bot commented Apr 16, 2026

Deploy preview

https://deploy-preview-1317--mui-internal.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@base-ui/react 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

Total duration: 16.65 ms 🔺+2.47 ms(+17.4%) | Renders: 4 (+0) | Paint: 72.87 ms +3.75 ms(+5.4%)

Test Duration Renders
HeavyList mount 10.34 ms 🔺+2.60 ms(+33.6%) 1 (+0)
DataGrid mount with paint timing 2.15 ms ▼-0.09 ms(-4.2%) 1 (+0)
Counter click 4.16 ms ▼-0.04 ms(-1.0%) 2 (+0)

Details of benchmark changes


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

@JCQuintas JCQuintas self-assigned this Apr 16, 2026
@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: docs-infra Involves the docs-infra product (https://www.notion.so/mui-org/b9f676062eb94747b6768209f7751305). labels Apr 16, 2026
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: out-of-date The pull request has merge conflicts and can't be merged. scope: docs-infra Involves the docs-infra product (https://www.notion.so/mui-org/b9f676062eb94747b6768209f7751305). 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