History

fix(desktop): boot the main window unthrottled so cold start paints at full speed (#7460)

Theo Browne committed 2 months ago

Commit efcf7d11 parent e7f6a302 files · +43 −1Browse files

Unified · Split

2 files
  1. apps/desktop/src/window/DesktopWindow.test.ts +32 −1
  2. apps/desktop/src/window/DesktopWindow.ts +11 −0
apps/desktop/src/window/DesktopWindow.test.ts+32−1
@@ -80,6 +80,7 @@ function makeFakeBrowserWindow() { · 79 unmodified lines
80 reload: vi.fn(),80 reload: vi.fn(),
81 replaceMisspelling: vi.fn(),81 replaceMisspelling: vi.fn(),
82 send: vi.fn(),82 send: vi.fn(),
83 setBackgroundThrottling: vi.fn(),
83 setWindowOpenHandler: vi.fn(),84 setWindowOpenHandler: vi.fn(),
84 };85 };
85 86
@@ -124,6 +125,7 @@ function makeFakeBrowserWindow() { · 38 unmodified lines
124 reload: webContents.reload,125 reload: webContents.reload,
125 send: webContents.send,126 send: webContents.send,
126 setZoomLevel: webContents.setZoomLevel,127 setZoomLevel: webContents.setZoomLevel,
128 setBackgroundThrottling: webContents.setBackgroundThrottling,
127 setAutoHideCursor: window.setAutoHideCursor,129 setAutoHideCursor: window.setAutoHideCursor,
128 webContentsListeners,130 webContentsListeners,
129 windowListeners,131 windowListeners,
@@ -455,7 +457,7 @@ describe("DesktopWindow", () => { · 325 unmodified lines
455 assert.isUndefined(createdWindowOptions[0]?.x);457 assert.isUndefined(createdWindowOptions[0]?.x);
456 assert.isUndefined(createdWindowOptions[0]?.y);458 assert.isUndefined(createdWindowOptions[0]?.y);
457 assert.isTrue(createdWindowOptions[0]?.disableAutoHideCursor);459 assert.isTrue(createdWindowOptions[0]?.disableAutoHideCursor);
458 assert.isUndefined(createdWindowOptions[0]?.webPreferences?.backgroundThrottling);460 assert.isFalse(createdWindowOptions[0]?.webPreferences?.backgroundThrottling);
459 assert.deepEqual(fakeWindow.setAutoHideCursor.mock.calls, [[false]]);461 assert.deepEqual(fakeWindow.setAutoHideCursor.mock.calls, [[false]]);
460 assert.deepEqual(fakeWindow.loadURL.mock.calls[0], ["t3code-dev://app/"]);462 assert.deepEqual(fakeWindow.loadURL.mock.calls[0], ["t3code-dev://app/"]);
461 assert.equal(fakeWindow.openDevTools.mock.calls.length, 1);463 assert.equal(fakeWindow.openDevTools.mock.calls.length, 1);
@@ -604,6 +606,35 @@ describe("DesktopWindow", () => { · 142 unmodified lines
604 }),606 }),
605 );607 );
606 608
609 // The window boots hidden with throttling disabled so first paint runs at
610 // full speed; the first reveal must hand it back to normal hidden-window
611 // throttling or a minimized window stays expensive forever.
612 it.effect("re-enables background throttling on first reveal", () =>
613 Effect.gen(function* () {
614 const fakeWindow = makeFakeBrowserWindow();
615 const createCount = yield* Ref.make(0);
616 const mainWindow = yield* Ref.make<Option.Option<Electron.BrowserWindow>>(Option.none());
617 const layer = makeTestLayer({
618 window: fakeWindow.window,
619 createCount,
620 mainWindow,
621 });
622
623 yield* Effect.gen(function* () {
624 const desktopWindow = yield* DesktopWindow.DesktopWindow;
625 yield* desktopWindow.handleBackendReady(new URL("http://127.0.0.1:3773"));
626
627 assert.equal(fakeWindow.setBackgroundThrottling.mock.calls.length, 0);
628 const readyToShow = fakeWindow.windowListeners.get("ready-to-show");
629 if (!readyToShow) {
630 return yield* Effect.die("window ready-to-show listener was not registered");
631 }
632 readyToShow();
633 assert.deepEqual(fakeWindow.setBackgroundThrottling.mock.calls, [[true]]);
634 }).pipe(Effect.provide(layer));
635 }),
636 );
637
607 it.effect("debounces move and resize bounds updates", () =>638 it.effect("debounces move and resize bounds updates", () =>
608 Effect.gen(function* () {639 Effect.gen(function* () {
609 const fakeWindow = makeFakeBrowserWindow();640 const fakeWindow = makeFakeBrowserWindow();
apps/desktop/src/window/DesktopWindow.ts+11−0
@@ -359,6 +359,12 @@ export const make = Effect.gen(function* () { · 358 unmodified lines
359 ...getWindowTitleBarOptions(shouldUseDarkColors, environment.platform),359 ...getWindowTitleBarOptions(shouldUseDarkColors, environment.platform),
360 webPreferences: {360 webPreferences: {
361 preload: environment.preloadPath,361 preload: environment.preloadPath,
362 // The window boots hidden (show: false until ready-to-show), and
363 // Chromium throttles hidden renderers: timers coalesce and rAF stops,
364 // which stalls first paint. Boot unthrottled; the first-reveal trigger
365 // re-enables throttling so a hidden or minimized window goes back to
366 // being cheap after it has been shown once.
367 backgroundThrottling: false,
362 contextIsolation: true,368 contextIsolation: true,
363 nodeIntegration: false,369 nodeIntegration: false,
364 sandbox: true,370 sandbox: true,
@@ -725,6 +731,11 @@ export const make = Effect.gen(function* () { · 360 unmodified lines
725 revealSubscribers.push((fire) => window.webContents.once("did-finish-load", fire));731 revealSubscribers.push((fire) => window.webContents.once("did-finish-load", fire));
726 }732 }
727 bindFirstRevealTrigger(revealSubscribers, () => {733 bindFirstRevealTrigger(revealSubscribers, () => {
734 // Boot is done; hand the window back to normal hidden-window throttling
735 // (see the backgroundThrottling comment on the create options above).
736 if (!window.isDestroyed()) {
737 window.webContents.setBackgroundThrottling(true);
738 }
728 // Reveal the real window, then close the connecting splash (if any) so the739 // Reveal the real window, then close the connecting splash (if any) so the
729 // two don't overlap and there's no blank gap between them.740 // two don't overlap and there's no blank gap between them.
730 if (persistedSettings.mainWindowMaximized) {741 if (persistedSettings.mainWindowMaximized) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t