From c61ff6ad638c20699447fd633029266494de32af Mon Sep 17 00:00:00 2001 From: Marc Kassubeck Date: Wed, 20 May 2026 21:27:10 +0200 Subject: [PATCH] perf: quick wins - webview minify, bounded timeline cache, focus-aware poll - Add minify: !watch to webview build script (reduces bundles ~25-33%) - Replace unbounded Map with bounded TimelineCache (cap 200) in PipelinesProvider - Skip notification polling when VS Code window is unfocused --- scripts/build-webviews.js | 1 + src/notifications/notificationService.ts | 1 + src/providers/pipelinesProvider.ts | 25 +++++++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/scripts/build-webviews.js b/scripts/build-webviews.js index 37246d5..755f7b1 100644 --- a/scripts/build-webviews.js +++ b/scripts/build-webviews.js @@ -21,6 +21,7 @@ const buildOptions = { format: 'iife', target: 'es2020', sourcemap: false, + minify: !watch, legalComments: 'none', logLevel: 'info' }; diff --git a/src/notifications/notificationService.ts b/src/notifications/notificationService.ts index c2e2034..9519ef8 100644 --- a/src/notifications/notificationService.ts +++ b/src/notifications/notificationService.ts @@ -86,6 +86,7 @@ export class NotificationService implements vscode.Disposable { private async pollOnce(): Promise { if (this._disposed || this._polling) { return; } if (!this._client.isConnected) { return; } + if (!vscode.window.state.focused) { return; } this._polling = true; try { let scopes; diff --git a/src/providers/pipelinesProvider.ts b/src/providers/pipelinesProvider.ts index 3a439f0..8dc85ea 100644 --- a/src/providers/pipelinesProvider.ts +++ b/src/providers/pipelinesProvider.ts @@ -181,12 +181,35 @@ type PipelinesTreeNode = | PipelineStepLogNode | vscode.TreeItem; +class TimelineCache { + private readonly _map = new Map(); + constructor(private readonly _maxSize: number) {} + + get(key: string): PipelineTimelineRecord[] | undefined { + return this._map.get(key); + } + + set(key: string, value: PipelineTimelineRecord[]): void { + if (this._map.size >= this._maxSize && !this._map.has(key)) { + const oldest = this._map.keys().next().value; + if (oldest !== undefined) { + this._map.delete(oldest); + } + } + this._map.set(key, value); + } + + clear(): void { + this._map.clear(); + } +} + export class PipelinesProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData = new vscode.EventEmitter(); readonly onDidChangeTreeData = this._onDidChangeTreeData.event; private _loading = false; - private readonly timelineCache = new Map(); + private readonly timelineCache = new TimelineCache(200); constructor( private readonly client: AdoClient,