Skip to content

perf(desktop): warm common route chunks while idle - #97037

Closed
helix4u wants to merge 2 commits into
NousResearch:mainfrom
helix4u:feat/desktop-idle-route-warmup
Closed

helix4u wants to merge 2 commits into
NousResearch:mainfrom
helix4u:feat/desktop-idle-route-warmup

Conversation

@helix4u

@helix4u helix4u commented Aug 28, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Warms the JavaScript chunks for five common Desktop routes after the gateway is open and the foreground has had time to settle. This removes the first-click chunk load/parse pause from Messaging, Artifacts, Cron, Settings, and Capabilities without moving those routes or their data fetches onto the startup critical path.

The warmup is deliberately bounded: it starts after a 1.5 second delay, uses requestIdleCallback when available, imports one chunk at a time with a 350 ms gap after completion, cancels if the gateway closes, and continues after an individual import failure. It runs only in the connected primary window; HUD, browser, and other auxiliary windows do not own normal navigation and do not pay this CPU or memory cost.

It warms code only. Each route still performs its authoritative data load when opened. Agents, Command Center, Profiles, Webhooks, and Starmap remain cold so Desktop does not eagerly parse every optional surface.

Related Issue

N/A

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Add a cancellable idle warmup scheduler for dynamic imports.
  • Serialize route imports by completion rather than merely staggering their start times.
  • Continue the queue after an individual chunk fails.
  • Share loader functions between React lazy routes and the warmup queue so each module uses the same cached dynamic import.
  • Warm Messaging, Artifacts, Cron, Settings, and Capabilities from one owner after gateway readiness.
  • Limit warmup to the connected primary window so HUD, browser, and auxiliary windows do not load routes they cannot navigate to.

How to Test

  1. Run npm --workspace apps/desktop exec vitest run src/lib/idle-warmup.test.ts src/app/contrib/route-loaders.test.ts.
  2. Run npm --workspace apps/desktop run typecheck.
  3. Run affected-file ESLint for the scheduler, route loaders, wiring, surfaces, and tests.

Focused result: 4 Vitest tests passed. Desktop renderer, Electron, and E2E typechecks passed. Affected-file ESLint and git diff --check passed.

Desktop performance series

This change is one independently reviewable layer of the same Desktop startup and first-interaction performance pass.

The three Python backend PRs share startup files but solve separate stages. Recommended landing order is #96749, then #96750, then #96751, rebasing the next PR only after the preceding one lands. #97032 is an independently reviewable Electron ordering change. The remaining renderer and Bot Mode PRs can also land independently; their effects compose without making cached state authoritative.
This PR owns idle code warmup: the connected primary window warms a small route set after the foreground settles, without prefetching route data.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Windows 11

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Not applicable. The focused tests verify serialization, cancellation, and failure continuation.

@helix4u
helix4u force-pushed the feat/desktop-idle-route-warmup branch from 6d9c6fa to 74ac8e7 Compare August 28, 2026 10:18
@helix4u
helix4u marked this pull request as ready for review August 28, 2026 10:30
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

perf(desktop): warm common route chunks while idle — idle-priority chunk preloading to remove first-click parse pause.

  • apps/desktop/src/lib/idle-warmup.ts:212 scheduleIdleWarmup — serializes dynamic imports via requestIdleCallback + gapMs:350 after initialDelayMs:1500. Each loader awaited before next scheduled, errors swallowed (catch(()=>undefined)) so one missing chunk doesn't block rest. Cancel unregisters both timeout and idle handles. Keeps parsing serialized so BG cannot compete with chat.
  • apps/desktop/src/app/contrib/route-loaders.ts:18 COMMON_ROUTE_WARMUP_LOADERS — only Messaging/Artifacts/Cron/Settings/Skills (light→heavy, frequent-first). Intentionally not preloading Agents/CommandCenter/Profiles/Webhooks/Starmap which are rarer/heavier.
  • apps/desktop/src/app/contrib/wiring.tsx:106 gated by shouldWarmCommonRoutes(gatewayOpen, auxiliaryWindow) — secondary HUD/browser windows don't warm, and disconnected primary doesn't either. Correct guard.
  • apps/desktop/src/lib/idle-warmup.test.ts:13 tests: serial wait, continue-after-failure, cancel-before-start.

Approve.

1 similar comment
@Enough1122

Copy link
Copy Markdown

AI code review — automated review for reference; please use your judgment.

perf(desktop): warm common route chunks while idle — idle-priority chunk preloading to remove first-click parse pause.

  • apps/desktop/src/lib/idle-warmup.ts:212 scheduleIdleWarmup — serializes dynamic imports via requestIdleCallback + gapMs:350 after initialDelayMs:1500. Each loader awaited before next scheduled, errors swallowed (catch(()=>undefined)) so one missing chunk doesn't block rest. Cancel unregisters both timeout and idle handles. Keeps parsing serialized so BG cannot compete with chat.
  • apps/desktop/src/app/contrib/route-loaders.ts:18 COMMON_ROUTE_WARMUP_LOADERS — only Messaging/Artifacts/Cron/Settings/Skills (light→heavy, frequent-first). Intentionally not preloading Agents/CommandCenter/Profiles/Webhooks/Starmap which are rarer/heavier.
  • apps/desktop/src/app/contrib/wiring.tsx:106 gated by shouldWarmCommonRoutes(gatewayOpen, auxiliaryWindow) — secondary HUD/browser windows don't warm, and disconnected primary doesn't either. Correct guard.
  • apps/desktop/src/lib/idle-warmup.test.ts:13 tests: serial wait, continue-after-failure, cancel-before-start.

Approve.

@helix4u

helix4u commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator Author
image

@helix4u

helix4u commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Closing because this was part of the older Desktop performance series and its route-wiring target has since been decomposed. The related series was measured and reduced to the portions with demonstrated gains, while this branch has no current-main product measurement that justifies rebuilding it. Any future route warming should start from current main with fresh timings.

@helix4u helix4u closed this Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/perf Performance improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants