一键导入
vscode-performance-and-compatibility
Guidance for improving VS Code extension performance, responsiveness, and compatibility across supported VS Code versions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guidance for improving VS Code extension performance, responsiveness, and compatibility across supported VS Code versions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Guidance for building, packaging, and releasing VS Code extensions with esbuild, vsce, and GitHub Actions workflows.
Guidance for implementing and modifying VS Code commands, menus, when clauses, and activation behavior.
Guidance for declaring, reading, updating, and reacting to VS Code extension configuration and settings changes safely.
Guidance for implementing and modifying VS Code extension architecture, activation flow, disposables, and extension-host-safe patterns.
Guidance for keeping VS Code extension localization, package.nls files, README content, and changelog updates in sync.
Guidance for implementing VS Code language features such as definitions, hovers, completions, symbols, diagnostics, formatting, and related providers.
| name | vscode-performance-and-compatibility |
| description | Guidance for improving VS Code extension performance, responsiveness, and compatibility across supported VS Code versions. |
VS Code extensions run inside the extension host process. Slow extensions degrade the entire VS Code experience. This guide covers the most important performance and compatibility considerations for extension authors.
activate() Workactivate() blocks loading of the extension and its contribution points. Keep it fast:
// BAD: Scanning the workspace synchronously on activation
export function activate(context: vscode.ExtensionContext): void {
const allFiles = fs.readdirSync(workspacePath); // ❌ blocks
}
// GOOD: Lazy initialization on first use
let index: FileIndex | undefined;
function getIndex(): FileIndex {
if (!index) {
index = new FileIndex(); // built on first provider call
}
return index;
}
// BAD
"activationEvents": ["*"]
// GOOD
"activationEvents": ["onLanguage:fxml", "onLanguage:java"]
Use onStartupFinished only for truly background tasks.
Use the built-in VS Code developer tools:
Help > Toggle Developer Tools > Performance[Extension Host] to see extension activation timeactivate() should complete in under 50 ms on a cold startNever use synchronous file I/O APIs in extension code:
// BAD
const content = fs.readFileSync(filePath, 'utf8'); // ❌ blocks event loop
// GOOD (Node.js fs.promises)
const content = await fs.promises.readFile(filePath, 'utf8');
// GOOD (VS Code workspace FS — works in all schemes including remote)
const bytes = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath));
const content = Buffer.from(bytes).toString('utf8');
Always prefer vscode.workspace.fs over Node.js fs — it works transparently with
Remote SSH, Dev Containers, and virtual file systems.
Provider methods receive a CancellationToken. Respect it in loops:
async provideDefinition(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.Location[] | undefined> {
for (const file of largeFileList) {
if (token.isCancellationRequested) { return undefined; }
await processFile(file);
}
return results;
}
For event-driven updates (e.g., re-validating on every keystroke), debounce expensive work:
let debounceTimer: NodeJS.Timeout | undefined;
context.subscriptions.push(
vscode.workspace.onDidChangeTextDocument((event) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
validateDocument(event.document);
}, 300); // wait 300 ms after the last change
})
);
Cache parsed results keyed on document.version to avoid redundant work:
const cache = new Map<string, { version: number; result: ParseResult }>();
function getParsed(document: vscode.TextDocument): ParseResult {
const cached = cache.get(document.uri.toString());
if (cached && cached.version === document.version) {
return cached.result;
}
const result = expensiveParse(document.getText());
cache.set(document.uri.toString(), { version: document.version, result });
return result;
}
Evict cache entries when documents close:
context.subscriptions.push(
vscode.workspace.onDidCloseTextDocument((doc) => cache.delete(doc.uri.toString()))
);
WeakMap<vscode.TextDocument, ...> for per-document state when possible (GC-friendly).Map / Set caches on workspace folder change.vscode API access.engines.vscode in package.json defines the minimum VS Code version.@since tag in the vscode.d.ts typings.// API added in VS Code 1.75
const tab = vscode.window.tabGroups?.activeTabGroup?.activeTab;
--vscodeVersion to @vscode/test-cli.Keep the packaged .vsix small:
bundle: true to tree-shake unused code..vscodeignore.npx @vscode/vsce ls to audit what is included.extensionUri.activate() completes in < 50 ms for cold start.readFileSync, existsSync, statSync) in hot paths.token.isCancellationRequested.document.version.context.subscriptions.