Extend the JS interop transport contract to allow passing UTF8 bytes instead of JS/.NET strings #35065
Labels
area-blazor
Includes: Blazor, Razor Components
enhancement
This issue represents an ask for new feature or an enhancement to an existing one
Perf
Milestone
Currently, the lowest level contract in JS interop is defined in terms of strings. That is:
Microsoft.JSInterop.JS
Microsoft.JSInterop
This is nice in that all environments have a notion of passing/receiving strings to/from the browser. In the case of WebView2, this is the only thing you can do. However Blazor Server and Blazor WebAssembly could actually exchange UTF8-encoded byte data if they wanted.
This makes things less efficient than they could be, because on the .NET side, JSON (de)serialization is done in terms of UTF8 bytes. So JS interop from JS to .NET currently:
Microsoft.JSInterop
If JSInterop's contract allowed for passing UTF8 bytes instead of a string, then we could:
byte[]
byte[]
or maybe aReadOnlySequence<byte>
without even copyingReadOnlySequence<byte>
(UTF8 data) to System.Text.JsonThat would reduce 2x copy-and-en/decode transformations to no transformations at all on the .NET side, possibly not even having to copy the data out of the SignalR message buffer, and just JSON-deserializing directly over that buffer.
Drawback
This complicates the underlying JS interop contract as there would be two ways to do the same thing, only one of which we'd be using in Blazor. Or we could do a breaking change and entirely remove the string-based APIs.
This would not affect regular applications since the transport is an internal detail. It would only affect people implementing platforms, which is probably nobody except us. It wouldn't even affect the
IJSRuntime
contract at all, because that's the contract used by application developers, not by platform authors. It would affect theJSRuntime
abstract base class that application developers don't normally use.For WebView, we'd need to take the byte data we're given on either side of the contract and encode it as a string for transport in/out of the WebView2 then convert back to byte data. This is probably no less efficient than what we have today, since it's the same number of transformations - they would just be happening in different places, and it would seem a bit more complicated inside the WebView2 code. I don't think it would be very difficult though.
I think we should consider doing this for .NET 7, but not in .NET 6 as we haven't budgeted time so late in the process for a significant change like this.
The text was updated successfully, but these errors were encountered: