Skip to content

perf(desktop): remember window bounds without electron-window-state - #49792

Merged
Hona merged 1 commit into
v2from
window-state
Sep 18, 2026
Merged

Hona merged 1 commit into
v2from
window-state

Conversation

@Hona

@Hona Hona commented Sep 18, 2026

Copy link
Copy Markdown
Member

Chromium startup trace of a packaged launch, browser process require() events:

187  electron-window-state  →  jsonfile, mkdirp, deep-equal (is-arguments, object-is,
                              which-boxed-primitive, es-get-iterator, …)
213  emoji-regex            ← next unrelated module: 26 ms later

The desktop uses x/y/width/height from the saved state and manage(win), which restores maximized/fullscreen and tracks the window until it closes. That is ~100 lines; the dependency's deep-equal tree is what made it 26 ms on every launch.

windows/window-state.ts:

  • readWindowState(file) + resolveWindowState(saved, defaults, displays) — same rules as the library: integer bounds required; bounds must still fit inside one current display, otherwise default size at (0,0) on the primary display; a saved maximized/fullscreen flag survives without bounds; anything unusable → defaults with no position (Electron centres)
  • manageWindowState(win, file, state, displays) — maximize/fullscreen on restore, debounced bounds capture on resize/move while the window is in its normal state, final write on closed (before the app's own closed handler that deletes the file for deliberately closed windows, same order as before)
  • Same file name (window-state-<id>.json) and same compact JSON shape, so existing profiles restore where they were
  • displays is injected, so the resolution rules are unit-tested without Electron
  • Drops electron-window-state from package.json

Measured with bun run bench:startup (#49758): packaged v2 build, isolated home, warm service, median of 6 launches.

baseline this PR
first main-process log line (app starting) 401 ms 380 ms
shell visible 1,325 ms 1,292 ms

Companion to #49791 (electron-store), which removes the other heavy CommonJS import on the same path.

electron-window-state pulls jsonfile, mkdirp and the deep-equal tree
(~25 packages) into every launch: 26 ms of CommonJS requires in the
startup trace before any of our code ran. The desktop only needs the
saved bounds, the maximized / fullscreen flags and a manage() that
tracks the window until it closes. Implement that in window-state.ts
with the same JSON file and validation rules (bounds must still fit a
current display, otherwise default size on the primary display) so
existing profiles restore where they were.

Packaged build, warm service, median of 6 launches: first main-process
log line 401 -> 380 ms after spawn.
Copilot AI lite review requested due to automatic review settings September 18, 2026 14:32
@Hona
Hona requested a review from Brendonovich as a code owner September 18, 2026 14:32

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 4facc03 into v2 Sep 18, 2026
10 checks passed
@Hona
Hona deleted the window-state branch September 18, 2026 23:41
jinhuang712 pushed a commit to jinhuang712/opencode that referenced this pull request Sep 26, 2026
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Track window bounds and the maximized/fullscreen flags in the same JSON
file electron-window-state wrote, so existing profiles restore where they
were, without loading the package at startup. Ported from upstream
4facc03; the module is named window-bounds because Forge already has a
window-state module.

No measurable startup change on a dev build.

Upstream: anomalyco/opencode@4facc03371 (anomalyco#49792)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Track window bounds and the maximized/fullscreen flags in the same JSON
file electron-window-state wrote, so existing profiles restore where they
were, without loading the package at startup. Ported from upstream
4facc03; the module is named window-bounds because Forge already has a
window-state module.

No measurable startup change on a dev build.

Upstream: anomalyco/opencode@4facc03371 (anomalyco#49792)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
Track window bounds and the maximized/fullscreen flags in the same JSON
file electron-window-state wrote, so existing profiles restore where they
were, without loading the package at startup. Ported from upstream
4facc03; the module is named window-bounds because Forge already has a
window-state module.

No measurable startup change on a dev build.

Upstream: anomalyco/opencode@4facc03371 (anomalyco#49792)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
…nomalyco#49792)

Track window bounds and the maximized/fullscreen flags in the same JSON
file electron-window-state wrote, so existing profiles restore where they
were, without loading the package at startup. Ported from upstream
4facc03; the module is named window-bounds because Forge already has a
window-state module.

No measurable startup change on a dev build.

Upstream: anomalyco/opencode@4facc03371 (anomalyco#49792)
divyanshusingh2903 added a commit to divyanshusingh2903/forge that referenced this pull request Oct 21, 2026
…nomalyco#49792)

Track window bounds and the maximized/fullscreen flags in the same JSON
file electron-window-state wrote, so existing profiles restore where they
were, without loading the package at startup. Ported from upstream
4facc03; the module is named window-bounds because Forge already has a
window-state module.

No measurable startup change on a dev build.

Upstream: anomalyco/opencode@4facc03371 (anomalyco#49792)
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