Skip to content

perf(widgets): lazy-load widget editors to keep undici out of the render path - #3

Merged
axisrow merged 3 commits into
mainfrom
perf/lazy-widget-editors
Sep 25, 2026
Merged

axisrow merged 3 commits into
mainfrom
perf/lazy-widget-editors

Conversation

@axisrow

@axisrow axisrow commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to PR #2 and upstream 35440e4 (sirmalloc#575): the eleven widget-editor implementations move into lazy chunks loaded via React lazy/Suspense, while preserving the synchronous renderEditor API. Render-time widget logic is unchanged; no new dependencies; the large diff is predominantly moving existing editor bodies.

Effect on the built, no-proxy piped render path:

PR #2 head this branch
fetches at startup 1 0
WASM initializations 1 0
undici in moduleLoadList loaded absent

The eager editor → Ink useInput → reconciler → Yoga route that survived both upstream sirmalloc#575 and PR #2 no longer executes on render.

Benchmark

13,009,445-byte synthetic transcript, 4 concurrent workers × 20 fresh processes each (one untimed warmup per worker), isolated HOME/USERPROFILE/CLAUDE_CONFIG_DIR, no proxy vars, tput-supplied width. Shared development host, so prefer the final clean sequence over the faster exploratory batches (all trials committed in docs/performance-397-results.json):

Runtime / revision CPU/render p50 p95
Node / PR #2 247.9 ms 239.9 ms 309.6 ms
Node / this branch 228.9 ms (−7.7%) 244.3 ms (−1.8%) 352.9 ms
Bun / PR #2 171.3 ms 153.7 ms 226.3 ms
Bun / this branch 149.5 ms (−12.7%) 132.9 ms 186.2 ms

Final Node p50 regressed 1.8%, so no universal latency improvement is claimed. Earlier recorded batches averaged −14.5% (Node) / −15.8% (Bun) CPU/render. Output hashes are identical across all revisions (454f8606…).

Editor first-open can suspend briefly (~300 ms observed in tests).

Tests

  • bun test: 2361 passed / 0 failed (single final run); new fresh-process regression test asserts the widget-registry import stays undici-free; fixed-latency sleeps in glyph/locale/timezone tests replaced with first-lazy-frame waits
  • bun run lint: clean, no suppressions
  • bun run build: successful; built piped renders verified on Node and Bun

Known blocker (pre-existing, deliberately out of scope)

docs/performance-397-verification.md documents that the distribution's Node 14 requirement is already broken on unmodified baseline: Bun does not lower ??=/class-field syntax for --target-version=14, and installed manifests require Node ≥22 (chalk 6) / ≥20 (Ink 6.2.0). This PR adds no newer JS syntax or Node APIs.

Artifacts

docs/performance-397-verification.md (adversarial verification of PR #2, verdict table), docs/performance-397-results.json (every 13 MB trial), scripts/benchmark-render.py (repro: CCSTATUSLINE_BENCH_DIR=/tmp/ccstatusline-bench python3 scripts/benchmark-render.py <node|bun> <dist.js> <label>).

Related: #2, sirmalloc#397, upstream 35440e4 (sirmalloc#575).

🤖 Generated with Claude Code

axisrow and others added 3 commits September 25, 2026 20:52
…wiring

- terminal: check the ancestor TTY before reassigning pid so each loop
  iteration reads as "one ps answer, one pid"; no call-order change
- claude-service-status: cover the lazy proxy-agent branch with tests
  (agent attached when HTTPS_PROXY is set, absent otherwise), matching
  the usage-fetch proxy coverage

Co-Authored-By: Claude Code <noreply@anthropic.com>
Extend the lazy TUI boundary from 35440e4 to widget editors: the registry previously initialized Ink's useInput/reconciler/Yoga graph on every piped render. Move editor implementations into lazy chunks and retain synchronous renderEditor APIs through React Suspense. Add an isolated startup regression check and wait for lazy editors in interaction tests.\n\nVerified: bun test (2361 pass), bun run lint, Node/Bun built renders and 13MB four-worker benchmarks. Node14 distribution build failure predates this change and is tracked separately in the perf verification report.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant