From 36a5ce2e821ee7bd1d5f478b4d23d5599ae838da Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 9 Apr 2025 14:59:24 -0700 Subject: [PATCH 1/3] Ignore updates with no changes for csharp files --- src/razor/src/document/razorDocumentManager.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/razor/src/document/razorDocumentManager.ts b/src/razor/src/document/razorDocumentManager.ts index ebaf4688e..94fbf5e12 100644 --- a/src/razor/src/document/razorDocumentManager.ts +++ b/src/razor/src/document/razorDocumentManager.ts @@ -237,6 +237,16 @@ export class RazorDocumentManager implements IRazorDocumentManager { ); } + if (updateBufferRequest.changes.length === 0 && !updateBufferRequest.previousWasEmpty) { + if (this.logger.verboseEnabled) { + this.logger.logVerbose( + `Update for '${updateBufferRequest.hostDocumentFilePath}' was empty. This shouldn't happen because it means the language server is doing extra work.` + ); + } + + return; + } + const hostDocumentUri = vscode.Uri.file(updateBufferRequest.hostDocumentFilePath); const document = this._getDocument(hostDocumentUri); const projectedDocument = document.csharpDocument; From 53ca75be70cb882f487a520e4afb1d8b21d07df0 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 9 Apr 2025 16:34:07 -0700 Subject: [PATCH 2/3] Only ignore for sending dynamic updates. Keep changes in system for synchronization --- .../src/document/IRazorDocumentChangeEvent.ts | 2 ++ .../src/document/razorDocumentManager.ts | 30 ++++++++----------- .../src/dynamicFile/dynamicFileInfoHandler.ts | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/razor/src/document/IRazorDocumentChangeEvent.ts b/src/razor/src/document/IRazorDocumentChangeEvent.ts index 8c75ecc42..83ed53cbf 100644 --- a/src/razor/src/document/IRazorDocumentChangeEvent.ts +++ b/src/razor/src/document/IRazorDocumentChangeEvent.ts @@ -3,10 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ServerTextChange } from '../rpc/serverTextChange'; import { IRazorDocument } from './IRazorDocument'; import { RazorDocumentChangeKind } from './razorDocumentChangeKind'; export interface IRazorDocumentChangeEvent { readonly document: IRazorDocument; readonly kind: RazorDocumentChangeKind; + readonly changes: ServerTextChange[]; } diff --git a/src/razor/src/document/razorDocumentManager.ts b/src/razor/src/document/razorDocumentManager.ts index 94fbf5e12..ed7351ca5 100644 --- a/src/razor/src/document/razorDocumentManager.ts +++ b/src/razor/src/document/razorDocumentManager.ts @@ -20,6 +20,7 @@ import { createDocument } from './razorDocumentFactory'; import { razorInitializeCommand } from '../../../lsptoolshost/razor/razorCommands'; import { PlatformInformation } from '../../../shared/platform'; import { v4 as uuidv4 } from 'uuid'; +import { ServerTextChange } from '../rpc/serverTextChange'; export class RazorDocumentManager implements IRazorDocumentManager { public roslynActivated = false; @@ -158,7 +159,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { const document = this._getDocument(uri); - this.notifyDocumentChange(document, RazorDocumentChangeKind.opened); + this.notifyDocumentChange(document, RazorDocumentChangeKind.opened, []); } public async ensureRazorInitialized() { @@ -189,7 +190,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { } } - this.notifyDocumentChange(document, RazorDocumentChangeKind.closed); + this.notifyDocumentChange(document, RazorDocumentChangeKind.closed, []); } private addDocument(uri: vscode.Uri): IRazorDocument { @@ -203,7 +204,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { document = createDocument(uri); this.razorDocuments[document.path] = document; - this.notifyDocumentChange(document, RazorDocumentChangeKind.added); + this.notifyDocumentChange(document, RazorDocumentChangeKind.added, []); return document; } @@ -212,7 +213,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { const document = this._getDocument(uri); delete this.razorDocuments[document.path]; - this.notifyDocumentChange(document, RazorDocumentChangeKind.removed); + this.notifyDocumentChange(document, RazorDocumentChangeKind.removed, []); } private findDocument(path: string) { @@ -237,16 +238,6 @@ export class RazorDocumentManager implements IRazorDocumentManager { ); } - if (updateBufferRequest.changes.length === 0 && !updateBufferRequest.previousWasEmpty) { - if (this.logger.verboseEnabled) { - this.logger.logVerbose( - `Update for '${updateBufferRequest.hostDocumentFilePath}' was empty. This shouldn't happen because it means the language server is doing extra work.` - ); - } - - return; - } - const hostDocumentUri = vscode.Uri.file(updateBufferRequest.hostDocumentFilePath); const document = this._getDocument(hostDocumentUri); const projectedDocument = document.csharpDocument; @@ -277,7 +268,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { updateBufferRequest.encodingCodePage ); - this.notifyDocumentChange(document, RazorDocumentChangeKind.csharpChanged); + this.notifyDocumentChange(document, RazorDocumentChangeKind.csharpChanged, updateBufferRequest.changes); } else { this.logger.logWarning( 'Failed to update the C# document buffer. This is unexpected and may result in incorrect C# interactions.' @@ -320,7 +311,7 @@ export class RazorDocumentManager implements IRazorDocumentManager { htmlProjectedDocument.update(updateBufferRequest.changes, updateBufferRequest.hostDocumentVersion); - this.notifyDocumentChange(document, RazorDocumentChangeKind.htmlChanged); + this.notifyDocumentChange(document, RazorDocumentChangeKind.htmlChanged, updateBufferRequest.changes); } else { this.logger.logWarning( 'Failed to update the HTML document buffer. This is unexpected and may result in incorrect HTML interactions.' @@ -328,16 +319,19 @@ export class RazorDocumentManager implements IRazorDocumentManager { } } - private notifyDocumentChange(document: IRazorDocument, kind: RazorDocumentChangeKind) { + private notifyDocumentChange(document: IRazorDocument, kind: RazorDocumentChangeKind, changes: ServerTextChange[]) { if (this.logger.verboseEnabled) { this.logger.logVerbose( - `Notifying document '${getUriPath(document.uri)}' changed '${RazorDocumentChangeKind[kind]}'` + `Notifying document '${getUriPath(document.uri)}' changed '${RazorDocumentChangeKind[kind]}' with '${ + changes.length + }' changes.` ); } const args: IRazorDocumentChangeEvent = { document, kind, + changes, }; this.onChangeEmitter.fire(args); diff --git a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts index 7662a1348..911af0bd1 100644 --- a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts +++ b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts @@ -40,7 +40,7 @@ export class DynamicFileInfoHandler { } ); this.documentManager.onChange(async (e) => { - if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen) { + if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen && e.changes.length > 0) { const uriString = UriConverter.serialize(e.document.uri); const identifier = TextDocumentIdentifier.create(uriString); await vscode.commands.executeCommand( From 6b7083d374d78c0d0221e6f068a0a35af42f493c Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Wed, 9 Apr 2025 17:28:48 -0700 Subject: [PATCH 3/3] Update src/razor/src/dynamicFile/dynamicFileInfoHandler.ts --- src/razor/src/dynamicFile/dynamicFileInfoHandler.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts index 911af0bd1..e54873ab1 100644 --- a/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts +++ b/src/razor/src/dynamicFile/dynamicFileInfoHandler.ts @@ -40,6 +40,8 @@ export class DynamicFileInfoHandler { } ); this.documentManager.onChange(async (e) => { + // Ignore any updates without text changes. This is important for perf since sending an update to roslyn does + // a round trip for producing nothing new and causes a lot of churn in solution updates. if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen && e.changes.length > 0) { const uriString = UriConverter.serialize(e.document.uri); const identifier = TextDocumentIdentifier.create(uriString);