Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

Problem

Users see dock icon but no window for 6-13s during app startup (varies by machine: ~6s on M3, ~13s on M1).

Even with lazy-loaded services (#223), the renderer makes IPC calls on mount which requires services to be loaded first, so the main window can't appear until everything is ready.

Solution

Added native splash screen that appears instantly (<100ms) while services load.

Implementation

Three-phase startup:

  1. Show splash - Native BrowserWindow with static HTML (<100ms)

    • No React, no IPC, no heavy dependencies
    • Matches app theme colors from colors.tsx
    • Shows "Loading services..." with spinner
  2. Load services - Happens while splash is visible (~6-13s)

    • Config, IpcMain, AI SDK, tokenizer modules
    • User gets instant visual feedback
  3. Show main window - Close splash, reveal app

    • Services guaranteed ready when window appears
    • Main window uses "ready-to-show" event to avoid white flash

Changes

  • Added static/splash.html - Lightweight loading screen matching app theme
  • Modified src/main.ts - Three-phase startup with splash screen
  • Updated Makefile - Copy splash.html to dist during build

Benefits

  • ✅ Instant visual feedback (<100ms vs 6-13s black screen)
  • ✅ No user confusion ("is it broken?")
  • ✅ Services guaranteed ready (no race conditions)
  • ✅ Clean transition to main window
  • ✅ All tests pass (410 tests)

Testing

Manually tested on M3 - splash appears instantly, main window appears ~6s later.

Generated with cmux

## Problem

Users see dock icon but no window for 6-13s during app startup (varies by machine).
Even with lazy-loaded services (#223), the renderer makes IPC calls on mount which
requires services to be loaded first, so the main window can't appear until everything
is ready.

## Solution

Added native splash screen that appears instantly (<100ms) while services load.

## Implementation

**Three-phase startup:**

1. **Show splash** - Native BrowserWindow with static HTML (<100ms)
   - No React, no IPC, no heavy dependencies
   - Matches app theme colors from colors.tsx
   - Shows "Loading services..." with spinner

2. **Load services** - Happens while splash is visible (~6-13s)
   - Config, IpcMain, AI SDK, tokenizer modules
   - User gets instant visual feedback

3. **Show main window** - Close splash, reveal app
   - Services guaranteed ready when window appears
   - Main window uses "ready-to-show" event to avoid white flash

## Changes

- **Added `static/splash.html`** - Lightweight loading screen matching app theme
- **Modified `src/main.ts`** - Three-phase startup with splash screen
- **Updated `Makefile`** - Copy splash.html to dist during build

## Benefits

- ✅ Instant visual feedback (<100ms vs 6-13s black screen)
- ✅ No user confusion ("is it broken?")
- ✅ Services guaranteed ready (no race conditions)
- ✅ Clean transition to main window
- ✅ All tests pass (410 tests)

_Generated with `cmux`_
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

…le during heavy loading

The issue was services were loading inside createWindow(), so splash closed
immediately after loading finished. Now services load while splash is visible,
giving proper visual feedback during the 6-13s startup time.
The real delay is loading the renderer (React app, JS parsing), not services.
Now splash stays visible until the main window's ready-to-show event fires,
keeping it on screen for the full 6-13s startup time.

Console output will now be:
- Showing splash screen...
- Loading services...
- Services loaded in ~100ms
- [6-13s delay while renderer loads]
- Main window ready to show
- Closing splash screen...
- Tokenizer modules loaded
- Set transparent: false for better visibility
- Add show: true to ensure splash appears immediately
- Add error handling and success logging for splash.html loading
- Fix parallel build: mkdir -p dist before copying splash.html

This addresses Codex P1 comment about parallel build race condition.
Key fixes:
- Make showSplashScreen() async and await loadFile() before showing
- Set show: false initially, then show() after HTML loads
- This ensures splash is visible BEFORE services load
- Add millisecond timestamps to all startup console.logs for debugging

Now the sequence will be:
1. [timestamp] Showing splash screen...
2. [timestamp] Splash screen loaded and visible (Xms)
3. [timestamp] Loading services...
4. [timestamp] Services loaded in Xms
5. [6-13s delay while renderer loads]
6. [timestamp] Main window ready to show
7. [timestamp] Closing splash screen...
8. [timestamp] Tokenizer modules loaded
Example output:
[13:25:10.092] Showing splash screen...
[13:25:10.200] Splash screen loaded and visible (108ms)
[13:25:10.201] Loading services...
[13:25:10.303] Services loaded in 102ms
[13:25:18.478] Tokenizer modules loaded
[13:25:18.877] Main window ready to show
[13:25:18.878] Closing splash screen...
The splash window.show() call was happening but the OS/Electron wasn't
actually rendering it before we continued. Adding a small delay ensures
the splash is visible on screen before we start the heavy work.

This makes the splash actually appear for the full 8+ seconds of loading
instead of only flashing briefly at the end.
Instead of blindly delaying 100ms, properly wait for:
1. The 'show' event to fire (window is shown)
2. setImmediate to give event loop a tick for painting

This ensures the splash is actually rendered before we block the
main thread with createWindow() and renderer loading.
@ammario ammario merged commit e48dafa into main Oct 13, 2025
6 of 7 checks passed
@ammario ammario deleted the faster-startup-and-lowercase branch October 13, 2025 18:50
ammar-agent added a commit that referenced this pull request Oct 13, 2025
## Problem
- Splash screen sometimes showed white flash during startup
- No user-visible error messages when startup fails
- Users see black screen with no feedback if app fails to start

## Solution

### 1. Fix White Flash
Added `backgroundColor: '#1f1f1f'` to splash window configuration to match
the splash HTML background color (hsl(0 0% 12%)). This eliminates any white
flash if HTML loads slowly.

### 2. Comprehensive Error Handling
Wrapped entire `app.whenReady()` in try/catch to handle all startup failures:
- Close splash screen on error
- Show error dialog with full error message and stack trace
- Quit app gracefully after showing error
- Ensures users always see startup failures instead of silent black screen

### 3. Update Documentation
- Corrected service load time comment (~100ms, not ~6-13s)
- Added note that spinner may freeze briefly during service loading
- This is acceptable since splash still provides visual feedback

## Impact
- ✅ No white flash - consistent dark background from first frame
- ✅ Better error UX - users see what went wrong during startup
- ✅ More accurate documentation of startup timing

## Related
- Builds on PR #226 (initial splash screen)
- Complements PR #230 (E2E test fixes)
- See issue #231 for future tree-shaking optimization

The backgroundColor fix and error handling are simple, reliable improvements
that don't add complexity. Future performance gains should come from loading
less code (tree-shaking) rather than moving work to worker threads.
ammar-agent added a commit that referenced this pull request Oct 13, 2025
## Problem
- Splash screen sometimes showed white flash during startup
- No user-visible error messages when startup fails
- Users see black screen with no feedback if app fails to start

## Solution

### 1. Fix White Flash
Added `backgroundColor: '#1f1f1f'` to splash window configuration to match
the splash HTML background color (hsl(0 0% 12%)). This eliminates any white
flash if HTML loads slowly.

### 2. Comprehensive Error Handling
Wrapped entire `app.whenReady()` in try/catch to handle all startup failures:
- Close splash screen on error
- Show error dialog with full error message and stack trace
- Quit app gracefully after showing error
- Ensures users always see startup failures instead of silent black screen

### 3. Update Documentation
- Corrected service load time comment (~100ms, not ~6-13s)
- Added note that spinner may freeze briefly during service loading
- This is acceptable since splash still provides visual feedback

## Impact
- ✅ No white flash - consistent dark background from first frame
- ✅ Better error UX - users see what went wrong during startup
- ✅ More accurate documentation of startup timing

## Related
- Builds on PR #226 (initial splash screen)
- Complements PR #230 (E2E test fixes)
- See issue #231 for future tree-shaking optimization

The backgroundColor fix and error handling are simple, reliable improvements
that don't add complexity. Future performance gains should come from loading
less code (tree-shaking) rather than moving work to worker threads.
ammar-agent added a commit that referenced this pull request Oct 13, 2025
## Problem
- Splash screen sometimes showed white flash during startup
- No user-visible error messages when startup fails
- Users see black screen with no feedback if app fails to start

## Solution

### 1. Fix White Flash
Added `backgroundColor: '#1f1f1f'` to splash window configuration to match
the splash HTML background color (hsl(0 0% 12%)). This eliminates any white
flash if HTML loads slowly.

### 2. Comprehensive Error Handling
Wrapped entire `app.whenReady()` in try/catch to handle all startup failures:
- Close splash screen on error
- Show error dialog with full error message and stack trace
- Quit app gracefully after showing error
- Ensures users always see startup failures instead of silent black screen

### 3. Update Documentation
- Corrected service load time comment (~100ms, not ~6-13s)
- Added note that spinner may freeze briefly during service loading
- This is acceptable since splash still provides visual feedback

## Impact
- ✅ No white flash - consistent dark background from first frame
- ✅ Better error UX - users see what went wrong during startup
- ✅ More accurate documentation of startup timing

## Related
- Builds on PR #226 (initial splash screen)
- Complements PR #230 (E2E test fixes)
- See issue #231 for future tree-shaking optimization

The backgroundColor fix and error handling are simple, reliable improvements
that don't add complexity. Future performance gains should come from loading
less code (tree-shaking) rather than moving work to worker threads.
github-merge-queue bot pushed a commit that referenced this pull request Oct 13, 2025
)

## Problem

While the splash screen from PR #226 provides instant visual feedback,
two issues remain:

1. **White flash** - Splash window sometimes shows white background
briefly before HTML loads
2. **Silent startup failures** - If the app fails to start, users see
nothing (no window, no error)

## Solution

### Fix White Flash

Set `backgroundColor: '#1f1f1f'` on splash window to match the HTML
background color. This ensures consistent dark background even if HTML
hasn't rendered yet.

### Comprehensive Error Handling

Wrap entire `app.whenReady()` in try/catch to handle all startup
failures:
- Close splash screen if startup fails
- Show error dialog with full error message and stack trace  
- Quit app gracefully after showing error
- Users always see what went wrong instead of silent black screen

### Documentation Updates

- Corrected service load time (~100ms, not ~6-13s) in code comments
- Added note that spinner may freeze briefly during service loading
- This is acceptable since splash still provides visual feedback

## Testing

- ✅ TypeScript checks pass
- ✅ ESLint passes (only pre-existing warnings)
- ✅ Manual testing confirms no white flash
- ✅ Error handling tested by introducing deliberate startup error

## Impact

- ✅ No white flash - consistent dark background from first frame
- ✅ Better error UX - users see what went wrong during startup  
- ✅ More accurate documentation

## Related

- Builds on PR #226 (splash screen)
- Complements PR #230 (E2E test fixes)
- See issue #231 for future tree-shaking optimization

Simple, reliable improvements without added complexity.

_Generated with `cmux`_

---------

Co-authored-by: Ammar Bandukwala <[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