Skip to content

feat: show window instantly with cached theme background#26

Merged
oahsiao merged 1 commit into
mainfrom
feat/instant-window-startup-bg
Jun 21, 2026
Merged

feat: show window instantly with cached theme background#26
oahsiao merged 1 commit into
mainfrom
feat/instant-window-startup-bg

Conversation

@oahsiao

@oahsiao oahsiao commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Speeds up the perceived cold-start of the app by showing the BrowserWindow
the moment it is created — instead of waiting for the renderer to finish its
first paint — and seeds it with the correct theme background so dark-theme
users no longer see a white flash before the UI appears.

The window background color is read from a small cache (startup.json) that the
renderer writes every time a theme is applied, so the next cold start paints with
the right color immediately.

Changes

File Change
src/main/main.js New startupBackground() helper reads userData/startup.jsonbg, validates against /^#[0-9a-fA-F]{3,8}$/, falls back to default theme bg #f4f4f4. Window now uses explicit show: true + backgroundColor: startupBackground(). Wrapped in try/catch so first launch (no cache) never throws.
src/main/ipc.js New app:setStartupBg handler: validates hex color (same regex), writes { "bg": <color> } to userData/startup.json via fs.writeFileSync, returns true/false. Full try/catch. Added app to the electron import.
src/preload/preload.js Exposes setStartupBg: (color) => ipcRenderer.invoke('app:setStartupBg', color) on the existing m2scout contextBridge API. contextIsolation: true / nodeIntegration: false unchanged.
src/renderer/js/themes.js In apply(), after setting CSS variables, caches the current vars['--bg'] via window.m2scout.setStartupBg(...) (existence-checked + try/catch). Runs on every theme switch and on init().

How it works

  1. Renderer applies a theme → caches its --bg to userData/startup.json.
  2. Next cold start → main process reads that file and paints the window with the
    correct color immediately, then shows content as the renderer loads.

What this does NOT fix (by design / out of scope)

  • Eliminates the wait for the renderer's first full paint → window appears
    earlier; content fills in right after.
  • The Electron runtime cold-start and Windows Defender / SmartScreen scanning
    of electron.exe cannot be removed by app code.
  • npm start (electron .) is slower than running
    node_modules/electron/dist/electron.exe directly (extra npm/node layer);
    a packaged asar build is typically fastest.
  • app.getPath('userData') may point to an app-name folder in dev mode; set and
    get use the same path, so it stays consistent.

Testing

  • node --check on all four modified files → OK.
  • npm test → 5 pass / 0 fail.
  • Smoke test: app launched for ~6s, no stderr, clean exit.

Speed up perceived cold-start by showing the BrowserWindow as soon as it is
created instead of waiting for the renderer's first paint, and seed it with
the correct theme background so dark-theme users don't see a white flash.

- main.js: add startupBackground() helper that reads the cached bg from
  userData/startup.json (validated against /^#[0-9a-fA-F]{3,8}$/), falling
  back to the default theme bg (#f4f4f4). Window now uses explicit show: true
  and backgroundColor: startupBackground().
- ipc.js: add app:setStartupBg handler that validates a hex color and writes
  { "bg": <color> } to userData/startup.json (try/catch, returns bool). Import
  app from electron.
- preload.js: expose setStartupBg(color) on the m2scout bridge.
- themes.js: cache the current theme --bg via m2scout.setStartupBg on every
  theme apply/init.
@oahsiao oahsiao merged commit 9d5e01c into main Jun 21, 2026
3 checks passed
@oahsiao oahsiao mentioned this pull request Jun 21, 2026
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