Skip to content

perf(stdlib): shorten the capture wait before modules load - #48

Merged
afonsojramos merged 8 commits into
mainfrom
perf/stdlib-capture
Oct 1, 2026
Merged

afonsojramos merged 8 commits into
mainfrom
perf/stdlib-capture

Conversation

@afonsojramos

@afonsojramos afonsojramos commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Summary

stdlib's preload holds every later module until its webpack analysis is ready. Two parts of that wait got shorter, and nothing it resolves changed.

  • Needle scans. ComponentLibrary re-stringified every exported function once per component name: 4,064 functions × 155 names, about 204 ms on Spotify 1.3.3. Function source text is now computed once per function for the session (sourceOf, shared by src and findBy). Functions without "data-encore-id" are skipped before the name regexes run, which brings the scan to about 5 ms with an identical result. findBy now stops at its first failing test instead of running every test.
  • Registry quiet wait. The xpui chunk promises were released after three consecutive unchanged 100 ms polls. Under a busy main thread that came to about 480 ms after the last registration. They are now released once the registry has been unchanged for 300 ms of wall time, checked every 25 ms. A chunk load in flight through wpr.l holds the release, which the old poll could not see. The 10 s cap is unchanged.

The quiet wait itself is still needed. In a live boot, 112 modules register about 140 ms after capture, from lazy chunks Spotify requests right after first render. GenericModal, Cards.Playlist, UI.Accordion and UI.ChipGroup come from that batch, so releasing on the first quiet tick would leave them undefined.

Two existing bugs are fixed along the way:

  • The component regex was built in a template literal, where \w and \$ cook to w and $. The identifier class only matched one-letter member names. It is now String.raw. Today's client still uses one-letter names, and both versions find the same 61 components.
  • If resolveChunk threw inside the wrapped wpr.l callback, webpack's done never ran and the lazy chunk hung. The error is now logged and done always runs. A synchronous throw from load also undoes the in-flight count.

Bumps stdlib to 1.13.2 and the stdlib version the kit tracks.

Results

Spotify 1.3.3.264, macOS arm64, 19 modules, with the startup CLI from spicetify/cli#4009 applied for both. These are 8 interleaved cold boots per stdlib, with the machine under heavy unrelated load (load average about 8).

Milestone stdlib 1.13.1 This branch
All modules loaded 2232 ms 1972 ms

After every boot on this branch, GenericModal, Cards.Playlist, UI.Accordion and UI.ChipGroup resolved, the UI library held 62 entries, and the boot report had no failed modules.

Validation

  • All 116 stdlib tests pass. New tests cover the quiet window, holding while a chunk is in flight, the cap, findBy short-circuiting with a single stringify, and sourceOf caching.
  • pnpm run check passes.
  • Live: the final commit was staged through ~/.config/spicetify/modules/stdlib with a full apply and checked over 4 boots plus 2 surface checks.

Not covered: a chunk that started loading before capture is not counted as in flight. That was already the case before, and in traced boots those chunks finished about 180 ms before capture. The analysis still snapshots wpr.m once, so a chunk requested after the quiet window is never analyzed; that also predates this change.

Summary by CodeRabbit

  • Bug Fixes
    • Improved component detection for exported components, including cases where matching patterns contain escaped characters.
    • Improved script-loading reliability by waiting for pending loads and registry activity to settle before releasing entry chunks, with a timeout fallback.
    • Improved search matching and value conversion, including consistent handling of nullish values and avoiding repeated conversion of the same objects and functions.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: c3f4e106-aa3f-4858-ac43-3072994b1206

📥 Commits

Reviewing files that changed from the base of the PR and between a1dce15 and fc28fb0.

📒 Files selected for processing (8)
  • modules/stdlib/metadata.json
  • modules/stdlib/src/util.test.mts
  • modules/stdlib/src/util.ts
  • modules/stdlib/src/webpack/ComponentLibrary.xpui.ts
  • modules/stdlib/src/webpack/index.ts
  • modules/stdlib/src/webpack/registry-quiet.test.mts
  • modules/stdlib/src/webpack/registry-quiet.ts
  • packages/kit/package.json

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

The stdlib adds cached source stringification, updates XPUI component matching, and changes when webpack entry chunks are released. Tests cover source matching and registry quiet-period behavior. Package metadata advances the stdlib version to 1.13.2.

Changes

Stdlib runtime updates

Layer / File(s) Summary
Cached source matching
modules/stdlib/src/util.ts, modules/stdlib/src/util.test.mts
sourceOf stringifies primitive values and caches object and function source by identity. findBy uses sourceOf for string and regex searches and stops at the first failing predicate. Tests cover caching and repeated searches.
Webpack source matching
modules/stdlib/src/webpack/index.ts, modules/stdlib/src/webpack/ComponentLibrary.xpui.ts
Webpack aliases src to sourceOf. XPUI component matching preserves regex escapes, reads each source once, and selects the first matching component name when the source contains data-encore-id.
Entry-chunk release tracking
modules/stdlib/src/webpack/index.ts, modules/stdlib/src/webpack/registry-quiet.ts, modules/stdlib/src/webpack/registry-quiet.test.mts, modules/stdlib/metadata.json, packages/kit/package.json
The script loader tracks in-flight loads. watchRegistryQuiet releases entry chunks after 300 ms without registry changes or pending chunks, or after a 10-second cap. Tests cover both conditions. Package metadata advances the stdlib version to 1.13.2.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant ScriptLoader
  participant RegistryQuietWatcher
  participant ModuleRegistry
  participant EntryChunkResolver
  ScriptLoader->>RegistryQuietWatcher: Report in-flight chunk count
  RegistryQuietWatcher->>ModuleRegistry: Check module count every 25 ms
  RegistryQuietWatcher->>EntryChunkResolver: Call onQuiet after 300 ms quiet or 10-second cap
Loading

Merge Risk: ⚪ Minimal · up to fc28f

This change shortens the stdlib preload wait and caches source text for component matching. No actionable merge-blocking risk was found. The stated limitations predate this change.

Security Architecture Review

Security architecture risk: 🔵 Low · up to fc28f

The inspected changes do not introduce an identified expansion of access or authority. Startup coordination becomes more aware of active loads, but unusual completion paths and incomplete runtime coverage leave limited uncertainty.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The supported affected scope is the host client session's component discovery and downstream module initialization. The inspected production contracts show no new external entrypoint or authority grant; deployment-wide and tenant-level exposure cannot be established from the available runtime evidence.

Trust Boundaries and Controls

  • observed — Source matching accepts existing client exports and retains exception-handled stringification. Cached strings remain private and identity-keyed, and matching selects existing exports rather than evaluating the captured text. This is a discovery mechanism, not a security validation boundary.

Resilience and Maintainability Implications

  • observed — The 10-second fallback intentionally releases even with a pending load, as it did before this PR. The new active-load check strengthens ordinary readiness coordination but does not make the fallback a complete-registry guarantee. Tests cover registry changes, pending-load delay, and timeout release; they do not establish every exceptional loader callback path.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary objective: reducing the stdlib preload capture wait before module loading. It is concise and directly related to the changes.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the source by moonlit light,
It caches each function tucked away from sight.
The registry ticks, then settles into rest,
The chunks are released when the count says “quiet” best.
I thump my paws beside the updated code,
And hop along the 1.13.2 road.

Comment @coderabbitai help to get the list of available commands.

@afonsojramos
afonsojramos merged commit 5355c1b into main Oct 1, 2026
6 checks passed
@afonsojramos
afonsojramos deleted the perf/stdlib-capture branch October 1, 2026 23:03
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