Skip to content

perf(desktop): create windows before the background service connects - #49763

Merged
Hona merged 1 commit into
v2from
startup-window-first
Sep 19, 2026
Merged

Hona merged 1 commit into
v2from
startup-window-first

Conversation

@Hona

@Hona Hona commented Sep 18, 2026

Copy link
Copy Markdown
Member

BackgroundServiceState.make awaited the first connection to the CLI service while its layer was being built, and desktop.ts only creates windows after every layer has built. So the renderer could not start loading its bundle until the main process had finished talking to the service.

gantt
  dateFormat X
  axisFormat %L
  section before
  build layers (incl. connect)   :a1, 0, 120
  create window, renderer loads  :a2, after a1, 400
  section after
  build layers                   :b1, 0, 90
  connect (forked)               :b2, 0, 120
  create window, renderer loads  :b3, after b1, 400
Loading
  • The initial connect is forked; connection awaits its first outcome through a Deferred, so no consumer observes the service before it exists and the failure path (die on connect error) is unchanged
  • reconnect behaviour is unchanged

On its own the gain is small: the WSL layer still waits for the bundled CLI's --version spawn, which dominates the same critical path. Together with #49762 (version cache) the window no longer waits on any CLI round-trip.

Measured with bun run bench:startup (#49758): packaged v2 build, isolated home, warm service, 5 launches, median ms since process spawn.

milestone baseline this PR #49762 alone #49762 + this PR
renderer process starts 851 838 512 480
window visible 1,085 1,071 778 744
shell visible 1,289 1,266 961 932

BackgroundServiceState awaited the first CLI service connection while
the layer was built, and windows are only created after every layer has
built. Fork the initial connect instead and let consumers await its
first outcome through 'connection', so the renderer loads its bundle
while the main process resolves the service.

On its own the gain is small because the WSL layer still awaits the CLI
version spawn; with the version cache (#49762) the renderer process
starts 32 ms earlier (512 -> 480 ms median) and the shell is visible at
932 ms instead of 961 ms.
@Hona
Hona requested a review from Brendonovich as a code owner September 18, 2026 12:44
Copilot AI lite review requested due to automatic review settings September 18, 2026 12:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Hona
Hona merged commit 5b565e8 into v2 Sep 19, 2026
10 checks passed
@Hona
Hona deleted the startup-window-first branch September 19, 2026 00:33
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Create the main windows before waiting on the sidecar health check; the
renderer already awaits the sidecar credentials over IPC, so it can paint
while the server boots. Also run the login-shell environment probe
asynchronously so it overlaps Electron startup and window creation instead
of blocking the main process.

On a dev build the renderer now reaches the server request at ~0.8s
instead of ~5.2-6.2s after launch.

Window ordering adapted from upstream 5b565e8 (anomalyco#49763) and
e1e2efe (anomalyco#49869); the async shell probe is Forge's own.
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Create the main windows before waiting on the sidecar health check; the
renderer already awaits the sidecar credentials over IPC, so it can paint
while the server boots. Also run the login-shell environment probe
asynchronously so it overlaps Electron startup and window creation instead
of blocking the main process.

On a dev build the renderer now reaches the server request at ~0.8s
instead of ~5.2-6.2s after launch.

Window ordering adapted from upstream 5b565e8 (anomalyco#49763) and
e1e2efe (anomalyco#49869); the async shell probe is Forge's own.

Upstream: anomalyco/opencode@5b565e8923 (anomalyco#49763)
Upstream: anomalyco/opencode@e1e2efe8ec (anomalyco#49869)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Create the main windows before waiting on the sidecar health check; the
renderer already awaits the sidecar credentials over IPC, so it can paint
while the server boots. Also run the login-shell environment probe
asynchronously so it overlaps Electron startup and window creation instead
of blocking the main process.

On a dev build the renderer now reaches the server request at ~0.8s
instead of ~5.2-6.2s after launch.

Window ordering adapted from upstream 5b565e8 (anomalyco#49763) and
e1e2efe (anomalyco#49869); the async shell probe is Forge's own.

Upstream: anomalyco/opencode@5b565e8923 (anomalyco#49763)
Upstream: anomalyco/opencode@e1e2efe8ec (anomalyco#49869)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Create the main windows before waiting on the sidecar health check; the
renderer already awaits the sidecar credentials over IPC, so it can paint
while the server boots. Also run the login-shell environment probe
asynchronously so it overlaps Electron startup and window creation instead
of blocking the main process.

On a dev build the renderer now reaches the server request at ~0.8s
instead of ~5.2-6.2s after launch.

Window ordering adapted from upstream 5b565e8 (anomalyco#49763) and
e1e2efe (anomalyco#49869); the async shell probe is Forge's own.

Upstream: anomalyco/opencode@5b565e8923 (anomalyco#49763)
Upstream: anomalyco/opencode@e1e2efe8ec (anomalyco#49869)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Create the main windows before waiting on the sidecar health check; the
renderer already awaits the sidecar credentials over IPC, so it can paint
while the server boots. Also run the login-shell environment probe
asynchronously so it overlaps Electron startup and window creation instead
of blocking the main process.

On a dev build the renderer now reaches the server request at ~0.8s
instead of ~5.2-6.2s after launch.

Window ordering adapted from upstream 5b565e8 (anomalyco#49763) and
e1e2efe (anomalyco#49869); the async shell probe is Forge's own.

Upstream: anomalyco/opencode@5b565e8923 (anomalyco#49763)
Upstream: anomalyco/opencode@e1e2efe8ec (anomalyco#49869)
Co-authored-by: Luke Parker <[email protected]>
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.

2 participants