Skip to content

perf(net): send ws binary messages without a Blob - #585

Open
0xmatthewb wants to merge 1 commit into
ranile:masterfrom
0xmatthewb:fix/net-ws-send-bytes-without-blob
Open

0xmatthewb wants to merge 1 commit into
ranile:masterfrom
0xmatthewb:fix/net-ws-send-bytes-without-blob

Conversation

@0xmatthewb

@0xmatthewb 0xmatthewb commented Oct 22, 2026 •

Copy link
Copy Markdown

Summary

Since #502, WebSocket::start_send copies each Message::Bytes into a Uint8Array and then wraps that copy in a new Blob before sending it. The copy is what makes sends work from shared wasm memory. The Blob contributes nothing to that fix, but Chrome registers every Blob with the browser process, so a client that sends binary frames continuously pays for one on every message. A Nym mixnet client in a Web Worker sends about 55 frames per second through this sink, and in V8 profiles of that worker on Android Chrome 145, creating and sending the Blobs took 9-27% of its busy time.

This change sends the copied Uint8Array directly with send_with_array_buffer_view. Because Uint8Array::from(&[u8]) goes through the copying typed-array constructor, the browser always receives a fresh, non-shared ArrayBuffer, so the #502 fix still holds. Message contents and boundaries, ordering relative to text messages, and the MessageSendError mapping are unchanged.

Validation

The gloo-net WebSocket tests pass in headless Chrome and Firefox, including websocket_works, which round-trips a Message::Bytes, and fmt and clippy are clean. On an Android Chrome 145 emulator, a Nym client built against this branch spends 2% of its worker's busy time on the send path, down from 27%.

`start_send` wraps every `Message::Bytes` in a new `Blob` (ranile#502), and
Chrome registers each Blob with the browser process. In Android Chrome
profiles of a Nym mixnet client in a worker, which sends dozens of
binary frames per second, creating and sending those Blobs takes 9-27%
of the worker's busy time.

`Uint8Array::from` already copies the bytes into a new, non-shared
ArrayBuffer, so sending that view directly keeps the shared-memory
fix from ranile#502 and drops the per-message Blob.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant