Skip to content

perf(startup): stop blocking dashboard-interactive on non-critical hydration (F5 first-load)#2209

Open
0xSolace wants to merge 1 commit into
cloud/mainfrom
sol/f5-firstload-nonblocking-hydrate
Open

perf(startup): stop blocking dashboard-interactive on non-critical hydration (F5 first-load)#2209
0xSolace wants to merge 1 commit into
cloud/mainfrom
sol/f5-firstload-nonblocking-hydrate

Conversation

@0xSolace

@0xSolace 0xSolace commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

LANE F2 sol-f5-firstload — post-login "takes forever" root fix. runHydrating() blocked HYDRATION_COMPLETE (dashboard-interactive) by serially awaiting wallet (1.3-12.4s), a VRM+world prefetch race (up to 15s), and a serial config chain. Fix: defer wallet, background the prefetch (loadGltfAsset joins in-flight via dedup map), parallelize config reads, void autonomy replay. Measured before->after on staging 3def4a82d: API-blocking critical path 8.84s -> 0.44s (95%); incl. prefetch up to ~23.8s -> 0.44s. Regression test asserts HYDRATION_COMPLETE fires even when all non-critical work hangs. Deliverable: projects/eliza-fleet/F5-FIRSTLOAD-2026-07-22.md.

Co-authored-by: shadow shadow@shad0w.xyz

Note

Stop blocking dashboard-interactive hydration on non-critical startup tasks

  • runHydrating in startup-phase-hydrate.ts now dispatches HYDRATION_COMPLETE without awaiting wallet fetch, VRM prefetch, world prefetch, or autonomy replay — these run fire-and-forget in the background.
  • Config and stream settings are fetched in parallel via Promise.allSettled; custom VRM and background probes are parallelized via Promise.all, reducing time to resolve avatar index.
  • A new test suite in startup-phase-hydrate-nonblocking.test.ts verifies hydration completes even when all non-critical calls hang indefinitely.
  • Behavioral Change: wallet addresses, VRM cache, world assets, and autonomy replay may not be available immediately after HYDRATION_COMPLETE is dispatched.

Macroscope summarized 85d3cf4.

…dration (F5 first-load)

Post-login "takes forever" root-fixed. runHydrating() gates HYDRATION_COMPLETE
-> phase 'ready' -> the dashboard actually rendering. It was serially AWAITING
work the landing (chat/companion) view never needs:

  1. getWalletAddresses() — awaited serially. Measured 1.3-12.4s (median ~7.8s)
     on cloud containers via the steward round-trip. Only consumed by the Eliza
     Cloud dashboard + wallets/inventory tab, never the landing view.
     -> now fire-and-forget; state populates when it resolves.

  2. VRM + gaussian-splat world prefetch — awaited via Promise.race([..., 15s]),
     blocking interactive for up to 15,000ms while 3D assets downloaded on cold
     cache. loadGltfAsset already joins in-flight prefetches via the inflight
     dedup map, so awaiting here was pure stall.
     -> now background warming; the companion scene still gets the warmed buffer
        with no duplicate fetch, we just no longer make the WHOLE app wait.

  3. Serial config chain (getConfig, getStreamSettings, hasCustomVrm,
     hasCustomBackground) + fetchAutonomyReplay awaited one-after-another though
     independent.
     -> config + streamSettings run via Promise.allSettled; custom vrm/bg probes
        (only when resolvedIdx===0) via Promise.all; autonomyReplay voided.

Measured on staging (3def4a82d), API-blocking critical path:
  before 8.84s -> after 0.44s (95% faster on the API portion).
  Including the awaited companion prefetch: ~11.8s typical / up to 23.8s worst
  -> 0.44s.

No spinner tricks — this removes real blocking work from time-to-interactive.
Regression test asserts HYDRATION_COMPLETE fires even when wallet, VRM prefetch,
world prefetch, and autonomy replay all hang indefinitely.

Co-authored-by: shadow <shadow@shad0w.xyz>
@macroscopeapp
macroscopeapp Bot requested a review from Dexploarer July 23, 2026 00:10
@github-actions

Copy link
Copy Markdown
Contributor

Credit balance is too low

@github-actions github-actions Bot added category:bugfix Auto-managed semantic PR category trust:established Established contributor (auto-managed) labels Jul 23, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 23, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

Unable to check for correctness in 85d3cf4. This PR changes the startup hydration contract by converting multiple blocking operations to fire-and-forget, dispatching HYDRATION_COMPLETE before wallet addresses, VRM prefetch, and autonomy replay are loaded. This is a significant runtime behavior change that affects what data is available after hydration completes.

You can customize Macroscope's approvability policy. Learn more.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 215 complexity · 3 duplication

Metric Results
Complexity 215
Duplication 3

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@0xSolace

Copy link
Copy Markdown
Contributor Author

Ported the demo-repo equivalent to elizaOS/eliza#16885 (the app-staging PWA deploys from elizaOS/eliza, not here).

Finding: eliza's runHydrating() already defers all shell-decoration fetches (wallet / config / streamSettings / autonomy replay) into decorateShellAfterReady() AFTER HYDRATION_COMPLETE (via the #15178 lineage), so the serial-await structure this PR fixed does not exist on that path. #16885 lands the durable regression test instead of a no-op code port, and includes a live staging startup-trace proving the demo's ~13.6s post-login stall is in first-run-required → starting-runtime (login/session + agent-base resolution), not the hydrate window. [sol-f2-port]

0xSolace added a commit to elizaOS/eliza that referenced this pull request Jul 23, 2026
…e F2 port) (#16885)

Ports the regression contract from milady-ai/milady#2209 to the demo repo
(elizaOS/eliza). The milady code fix (defer wallet, background VRM/world
prefetch, parallelize config reads, void autonomy replay) is UNNECESSARY here:
eliza's runHydrating already runs all shell-decoration work
(getWalletAddresses / getConfig / getStreamSettings / fetchAutonomyReplay)
inside decorateShellAfterReady(), fired AFTER dispatch(HYDRATION_COMPLETE),
via the #15178 lineage. So the app-core serial-await structure milady#2209
targeted does not exist on this path.

This test pins that invariant so a future refactor cannot silently re-await any
of those slow calls on the ready critical path: every decoration dependency
(wallet, config, stream settings, autonomy replay) hangs FOREVER and the test
proves HYDRATION_COMPLETE still fires (<3s), the wallet fetch is kicked off but
never blocks (its setter never runs before completion), and autonomy replay is
not awaited.

Evidence that the canary's 13.6s post-login stall is NOT in the hydrate window:
a live staging startup-trace (projects/eliza-fleet/F2-PORT-2026-07-22.md) shows
coordinator:hydrating -> coordinator:ready is ~4s and dominated by the
post-ready agent-base fetch waterfall + lazy chunks; the real 12.4s stall is in
first-run-required -> starting-runtime (login/session establish + agent-base
resolution), a separate phase this PR documents for follow-up lanes.

Co-authored-by: 0xSolace <sol@wakesync.dev>
Co-authored-by: shadow <shadow@shad0w.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category:bugfix Auto-managed semantic PR category trust:established Established contributor (auto-managed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant