diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 173fb488bcde6..ed02a196a8bc3 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1340,8 +1340,8 @@ export class BackLayerWebView extends Themable { } this.pendingWebviewIdleCreationRequest.set(content.source, runWhenIdle(() => { - const { message, renderer } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, true, true); - this._sendMessageToWebview(message); + const { message, renderer, transfer: transferable } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, true, true); + this._sendMessageToWebview(message, transferable); this.pendingWebviewIdleInsetMapping.set(content.source, { outputId: message.outputId, cellInfo: cellInfo, renderer, cachedCreation: message }); this.reversedPendingWebviewIdleInsetMapping.set(message.outputId, content.source); this.pendingWebviewIdleCreationRequest.delete(content.source); @@ -1380,8 +1380,8 @@ export class BackLayerWebView extends Themable { // create new output const createOutput = () => { - const { message, renderer } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, false, false); - this._sendMessageToWebview(message); + const { message, renderer, transfer: transferable } = this._createOutputCreationMessage(cellInfo, content, cellTop, offset, false, false); + this._sendMessageToWebview(message, transferable); this.insetMapping.set(content.source, { outputId: message.outputId, cellInfo: cellInfo, renderer, cachedCreation: message }); this.hiddenInsetMapping.delete(content.source); this.reversedInsetMapping.set(message.outputId, content.source); @@ -1390,7 +1390,7 @@ export class BackLayerWebView extends Themable { createOutput(); } - private _createOutputCreationMessage(cellInfo: T, content: IInsetRenderOutput, cellTop: number, offset: number, createOnIdle: boolean, initiallyHidden: boolean): { readonly message: ICreationRequestMessage; readonly renderer: INotebookRendererInfo | undefined } { + private _createOutputCreationMessage(cellInfo: T, content: IInsetRenderOutput, cellTop: number, offset: number, createOnIdle: boolean, initiallyHidden: boolean): { readonly message: ICreationRequestMessage; readonly renderer: INotebookRendererInfo | undefined; transfer: readonly ArrayBuffer[] } { const messageBase = { type: 'html', executionId: cellInfo.executionId, @@ -1402,6 +1402,8 @@ export class BackLayerWebView extends Themable { createOnIdle: createOnIdle } as const; + const transfer: ArrayBuffer[] = []; + let message: ICreationRequestMessage; let renderer: INotebookRendererInfo | undefined; if (content.type === RenderOutputType.Extension) { @@ -1409,9 +1411,11 @@ export class BackLayerWebView extends Themable { renderer = content.renderer; const first = output.outputs.find(op => op.mime === content.mimeType)!; - // TODO@jrieken - the message can contain "bytes" and those are transferable - // which improves IPC performance and therefore should be used. However, it does - // means that the bytes cannot be used here anymore + + // Copy the underlying buffer so we only send over the data we need + const valueBytes = new Uint8Array(first.data.buffer); + transfer.push(valueBytes.buffer); + message = { ...messageBase, outputId: output.outputId, @@ -1422,7 +1426,7 @@ export class BackLayerWebView extends Themable { metadata: output.metadata, output: { mime: first.mime, - valueBytes: first.data.buffer, + valueBytes: valueBytes, }, allOutputs: output.outputs.map(output => ({ mime: output.mime })), }, @@ -1442,7 +1446,8 @@ export class BackLayerWebView extends Themable { return { message, - renderer + renderer, + transfer, }; } @@ -1694,12 +1699,12 @@ export class BackLayerWebView extends Themable { }); } - private _sendMessageToWebview(message: ToWebviewMessage) { + private _sendMessageToWebview(message: ToWebviewMessage, transfer?: readonly ArrayBuffer[]) { if (this._disposed) { return; } - this.webview?.postMessage(message); + this.webview?.postMessage(message, transfer); } override dispose() {