Skip to content

Improve transfer of ArrayBuffers to and from webviews #115807

@mjbvz

Description

@mjbvz

Problem

There are currently two issues when you try posting a ArrayBuffer to a webview or from a webview back to VS Code:

  1. The ArrayBuffer is not revived. Instead the receiver ends up getting a JavaScript object literal with the contents of the array buffer

  2. Serialized messages for typed arrays are currently super inefficient . For example, a Uint8Array is serialized as "{ "0": 0, "1": 0, "2": 0, ... }"

API Proposal

In Webview.postMesssage, add a second parameter that lets extensions specify the types to 'transfer':

interface Webview {
    postMessage(message: any, transfer?: readonly ArrayBuffer[]): Promise<bool>;
} 

This is inspired by the postMessage web api, however to start with, we'd only allow transferring of array buffers.

When transfer is provided, we'd walk the message object to find any ArrayBuffer object that appear in the message and make sure these are more efficiently transferred. We'd also revive them properly on the other side (so if an ArrayBuffer goes in, then an ArrayBuffer object comes out too)

Other notes

Why not just always enable this behavior instead of requiring transfer?

We'd potentially break existing extensions that rely on the current serialized format of ArrayBuffers/typed arrays.

Having a transfer parameter also lets us really transfer the ArrayBuffer in cases where this is possible

Can we always "transfer" ownership of the ArrayBuffer the way that we can on web?

No, we can't.

Consider an extension running on a remote with a local webview for example. There is no way to actually transfer the ArrayBuffer between these contexts. Instead we have to serialize it and then recreate it on the other side.

However, this new api would still let us improve the serialization and reduce the amount of data transferred.

Even if we can't really transfer ownership, semantically, transfer should behave like window.postMessage in that extensions should not use transferred objects after they have transferred. I'm not sure if we can enforce this though

Can we support other types? Blob or OffscreenCanvas for example?

Potentially, but not all of them. Because we can't support transfer all the time (see above), we can only support types that can be serialized. This means no OffscreenCanvas or other rich objects.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions