How VS Code Achieves Sub‑Second Startup: Secrets from CovalenceConf 2019
This article summarizes the key techniques presented at CovalenceConf 2019 for optimizing Visual Studio Code's startup performance, covering measurement, bundling, V8 code caching, lifecycle phase ordering, requestIdleCallback, and perceived‑performance tricks that together reduce launch time to under one second.
At CovalenceConf 2019, the VS Code team shared how they dramatically improved the editor's startup speed, focusing on making the editor ready for editing as quickly as possible.
TL;DR
VS Code aims to let users start editing instantly.
Startup optimization is a collection of many small improvements, not a single silver bullet.
The Monaco editor began in 2011 as a browser‑based developer tool.
Performance Optimization Rules
Measure, measure, measure – use the Performance API to mark key points and build a baseline.
Monitor each release and react quickly to regressions.
Test on an old ThinkPad (7‑9 years old) and keep launch time under 1.8 seconds.
Focus on loading and executing code rather than low‑level Electron or V8 details.
Fast Code Loading
Bundle code into a single file with Rollup or Webpack (saves ~400 ms).
Compress the bundle (saves ~100 ms).
Use V8 cached data (or the v8-compile-cache package) to cache compiled bytecode (saves ~400 ms).
Lifecycle Phase Ordering
Prioritize rendering the file explorer and editor first.
Split the startup into four phases: Starting, Ready, Restored, and Eventually.
// src/vs/workbench/common/contributions.ts
start(accessor: ServicesAccessor): void {
const instantiationService = this.instantiationService = accessor.get(IInstantiationService);
const lifecycleService = this.lifecycleService = accessor.get(ILifecycleService);
[LifecyclePhase.Starting, LifecyclePhase.Ready, LifecyclePhase.Restored, LifecyclePhase.Eventually]
.forEach(phase => this.instantiateByPhase(instantiationService, lifecycleService, phase));
}
instantiateByPhase(instantiationService: IInstantiationService, lifecycleService: ILifecycleService, phase: LifecyclePhase): void {
if (lifecycleService.phase >= phase) {
this.doInstantiateByPhase(instantiationService, phase);
} else {
lifecycleService.when(phase).then(() => this.doInstantiateByPhase(instantiationService, phase));
}
}Using requestIdleCallback
Deferring non‑critical work to browser idle time with requestIdleCallback improves responsiveness compared to setTimeout. A timeout can be provided to guarantee execution after a maximum delay.
// busy work
requestIdleCallback((deadline) => {
// idle tasks
});Perceived Performance Tricks
Render UI elements like the breadcrumb and status bar before loading large files, giving the impression of a fast UI.
Replace MouseUp / Click with MouseDown for tab switches to reduce the 50 ms delay.
These strategies collectively reduced VS Code's JavaScript bundle load time from ~1.5 seconds to ~0.5 seconds and its overall startup to around 1 second (hot start ~500 ms).
References
CovalenceConf 2019: Visual Studio Code – The First Second (YouTube)
Web.dev performance guides
Google’s "Idle Until Urgent" article
V8 Code Cache blog post
Chromium blog on rapid page loads
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
