From a8c9128841eb953a2d3afbe445fc15e130f5cb0d Mon Sep 17 00:00:00 2001 From: Nick Gregory Date: Wed, 7 Jan 2026 16:04:49 -0800 Subject: [PATCH] improve SearchLineCache performance --- addons/addon-search/src/SearchLineCache.ts | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/addons/addon-search/src/SearchLineCache.ts b/addons/addon-search/src/SearchLineCache.ts index 535a3cc5..175f3919 100644 --- a/addons/addon-search/src/SearchLineCache.ts +++ b/addons/addon-search/src/SearchLineCache.ts @@ -38,6 +38,9 @@ export class SearchLineCache extends Disposable { private _linesCache: LineCacheEntry[] | undefined; private _linesCacheTimeout = this._register(new MutableDisposable()); private _linesCacheDisposables = this._register(new MutableDisposable()); + // Track access to avoid recreating a timeout on every init call which occurs once per search + // result (findNext/findPrevious -> _highlightAllMatches -> find loop). + private _lastAccessTimestamp = 0; constructor(private readonly _terminal: Terminal) { super(); @@ -57,15 +60,34 @@ export class SearchLineCache extends Disposable { ); } - this._linesCacheTimeout.value = disposableTimeout(() => this._destroyLinesCache(), Constants.LINES_CACHE_TIME_TO_LIVE); + this._lastAccessTimestamp = Date.now(); + if (!this._linesCacheTimeout.value) { + this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE); + } } private _destroyLinesCache(): void { this._linesCache = undefined; + this._lastAccessTimestamp = 0; this._linesCacheDisposables.clear(); this._linesCacheTimeout.clear(); } + private _scheduleLinesCacheTimeout(delay: number): void { + this._linesCacheTimeout.value = disposableTimeout(() => { + if (!this._linesCache) { + return; + } + const now = Date.now(); + const elapsed = now - this._lastAccessTimestamp; + if (elapsed >= Constants.LINES_CACHE_TIME_TO_LIVE) { + this._destroyLinesCache(); + return; + } + this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE - elapsed); + }, delay); + } + public getLineFromCache(row: number): LineCacheEntry | undefined { return this._linesCache?.[row]; }