diff --git a/src/vs/platform/windows/electron-main/window.ts b/src/vs/platform/windows/electron-main/window.ts index c7c9dfff9fe..524765294c1 100644 --- a/src/vs/platform/windows/electron-main/window.ts +++ b/src/vs/platform/windows/electron-main/window.ts @@ -247,8 +247,11 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - // Create the browser window. + // Create the browser window + mark('code/willCreateCodeBrowserWindow'); this._win = new BrowserWindow(options); + mark('code/didCreateCodeBrowserWindow'); + this._id = this._win.id; // Open devtools if instructed from command line args @@ -280,6 +283,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { } if (isFullscreenOrMaximized) { + mark('code/willMaximizeCodeWindow'); this._win.maximize(); if (this.windowState.mode === WindowMode.Fullscreen) { @@ -289,6 +293,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { if (!this._win.isVisible()) { this._win.show(); // to reduce flicker from the default window size to maximize, we only show after maximize } + mark('code/didMaximizeCodeWindow'); } this._lastFocusTime = Date.now(); // since we show directly, we need to set the last focus time too @@ -915,6 +920,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } private restoreWindowState(state?: IWindowState): [IWindowState, boolean? /* has multiple displays */] { + mark('code/willRestoreCodeWindowState'); + let hasMultipleDisplays = false; if (state) { try { @@ -927,6 +934,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } + mark('code/didRestoreCodeWindowState'); + return [state || defaultWindowState(), hasMultipleDisplays]; } diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index e512ac374ed..5a874111bcb 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1211,13 +1211,13 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const state = this.windowsStateHandler.getNewWindowState(configuration); // Create the window - mark('code/willCreateWindow'); + mark('code/willCreateCodeWindow'); const createdWindow = window = this.instantiationService.createInstance(CodeWindow, { state, extensionDevelopmentPath: configuration.extensionDevelopmentPath, isExtensionTestHost: !!configuration.extensionTestsPath }); - mark('code/didCreateWindow'); + mark('code/didCreateCodeWindow'); // Add as window tab if configured (macOS only) if (options.forceNewTabbedWindow) { diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index 3f2e11c2b84..8685eb5deb7 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -171,7 +171,7 @@ class PerfModelContentProvider implements ITextModelContentProvider { table.push(['require(main.bundle.js)', metrics.timers.ellapsedLoadMainBundle, '[main]', `initial startup: ${metrics.initialStartup}`]); table.push(['start crash reporter', metrics.timers.ellapsedCrashReporter, '[main]', `initial startup: ${metrics.initialStartup}`]); table.push(['serve main IPC handle', metrics.timers.ellapsedMainServer, '[main]', `initial startup: ${metrics.initialStartup}`]); - table.push(['create window', metrics.timers.ellapsedWindowCreate, '[main]', `initial startup: ${metrics.initialStartup}`]); + table.push(['create window', metrics.timers.ellapsedWindowCreate, '[main]', `initial startup: ${metrics.initialStartup}, ${metrics.initialStartup ? `state: ${metrics.timers.ellapsedWindowRestoreState}ms, widget: ${metrics.timers.ellapsedBrowserWindowCreate}ms, show: ${metrics.timers.ellapsedWindowMaximize}ms` : ''}`]); table.push(['app.isReady => window.loadUrl()', metrics.timers.ellapsedWindowLoad, '[main]', `initial startup: ${metrics.initialStartup}`]); table.push(['window.loadUrl() => begin to require(workbench.desktop.main.js)', metrics.timers.ellapsedWindowLoadToRequire, '[main->renderer]', StartupKindToString(metrics.windowKind)]); table.push(['require(workbench.desktop.main.js)', metrics.timers.ellapsedRequire, '[renderer]', `cached data: ${(metrics.didUseCachedData ? 'YES' : 'NO')}${stats ? `, node_modules took ${stats.nodeRequireTotal}ms` : ''}`]); diff --git a/src/vs/workbench/services/timer/browser/timerService.ts b/src/vs/workbench/services/timer/browser/timerService.ts index 1392f70a41c..0e392eb0548 100644 --- a/src/vs/workbench/services/timer/browser/timerService.ts +++ b/src/vs/workbench/services/timer/browser/timerService.ts @@ -201,10 +201,34 @@ export interface IStartupMetrics { * The time it took to create the window. * * * Happens in the main-process - * * Measured with the `willCreateWindow` and `didCreateWindow` performance marks. + * * Measured with the `willCreateCodeWindow` and `didCreateCodeWindow` performance marks. */ readonly ellapsedWindowCreate?: number; + /** + * The time it took to create the electron browser window. + * + * * Happens in the main-process + * * Measured with the `willCreateCodeBrowserWindow` and `didCreateCodeBrowserWindow` performance marks. + */ + readonly ellapsedBrowserWindowCreate?: number; + + /** + * The time it took to restore and validate window state. + * + * * Happens in the main-process + * * Measured with the `willRestoreCodeWindowState` and `didRestoreCodeWindowState` performance marks. + */ + readonly ellapsedWindowRestoreState?: number; + + /** + * The time it took to maximize/show the window. + * + * * Happens in the main-process + * * Measured with the `willMaximizeCodeWindow` and `didMaximizeCodeWindow` performance marks. + */ + readonly ellapsedWindowMaximize?: number; + /** * The time it took to tell electron to open/restore a renderer (browser window). * @@ -558,7 +582,10 @@ export abstract class AbstractTimerService implements ITimerService { ellapsedLoadMainBundle: initialStartup ? this._marks.getDuration('code/willLoadMainBundle', 'code/didLoadMainBundle') : undefined, ellapsedCrashReporter: initialStartup ? this._marks.getDuration('code/willStartCrashReporter', 'code/didStartCrashReporter') : undefined, ellapsedMainServer: initialStartup ? this._marks.getDuration('code/willStartMainServer', 'code/didStartMainServer') : undefined, - ellapsedWindowCreate: initialStartup ? this._marks.getDuration('code/willCreateWindow', 'code/didCreateWindow') : undefined, + ellapsedWindowCreate: initialStartup ? this._marks.getDuration('code/willCreateCodeWindow', 'code/didCreateCodeWindow') : undefined, + ellapsedWindowRestoreState: initialStartup ? this._marks.getDuration('code/willRestoreCodeWindowState', 'code/didRestoreCodeWindowState') : undefined, + ellapsedBrowserWindowCreate: initialStartup ? this._marks.getDuration('code/willCreateCodeBrowserWindow', 'code/didCreateCodeBrowserWindow') : undefined, + ellapsedWindowMaximize: initialStartup ? this._marks.getDuration('code/willMaximizeCodeWindow', 'code/didMaximizeCodeWindow') : undefined, ellapsedWindowLoad: initialStartup ? this._marks.getDuration('code/mainAppReady', 'code/willOpenNewWindow') : undefined, ellapsedWindowLoadToRequire: this._marks.getDuration('code/willOpenNewWindow', 'code/willLoadWorkbenchMain'), ellapsedRequire: this._marks.getDuration('code/willLoadWorkbenchMain', 'code/didLoadWorkbenchMain'),