dioxus
dioxus copied to clipboard
Desktop API to send large (1 MB+) payloads to Javascript
The eval
method for sending data to JavaScript cannot handle large payloads. In the following example, it freezes both the WebView and the backend when the payload exceeds 100k elements in debug mode, and 1M elements in release mode (on Windows 11, Git rev 53343bf).
use dioxus::prelude::*;
#[component]
fn Eval() -> Element {
let mut payload_size = use_signal(|| 100usize);
let received_size = use_resource(move || async move {
let handler = eval(
r#"
console.time('recv');
let msg = await dioxus.recv();
console.timeEnd('recv');
return msg.length;
"#,
)
.unwrap();
handler.send(vec![0u8; payload_size()].into()).unwrap();
handler.await.unwrap().as_i64().unwrap()
});
rsx! {
input {
r#type: "number",
value: "{payload_size}",
oninput: move |ev| payload_size.set(ev.value().parse().unwrap_or(0))
}
h1 { "Received {received_size.read():?}" }
}
}
fn main() {
launch(Eval)
}
Since eval
is not intended for large payloads/byte buffers, an alternative API supporting fast Rust->JS buffer transfers would be helpful. The API could look something like this:
let socket = use_binary_socket(r#"
// defines the onmessage handler when the socket is created
let ctx = document.getElementById("my-canvas").getContext("2d");
let img = new ImageData(new Uint8ClampedArray(ev.data), 1000, 1000);
ctx.putImageData(img, 0, 0);
"#);
socket.send(vec![0u8; 4_000_000]);
Also, the risks of using eval
should be communicated in documentation and/or with runtime warnings for payloads exceeding some size threshold.
We would really appreciate this feature if it became available. Being able to pipe pixel buffers in opens dioxus up to a whole heap of opportunities for our commercial applications.
You can send large chunks of binary data from rust to javascript with the custom asset handler added in https://github.com/DioxusLabs/dioxus/pull/1719
I think this issue can be closed now. At the time it was created, asset handlers which included non-trivial processing time (e.g. reading a WGPU render buffer and encoding it for display in an img
element) would cause other DOM edits to be applied in reverse order if the handler was called too frequently, which is what motivated trying eval
and then finding that it also broke things.
That edit order bug with asset handlers doesn't happen in 0.5.1. The framerate of updates is still too low, but for now I think that's from my sub-optimal usage of the asset handler, so another solution for byte-buffer transfers probably isn't needed.
@thorn132 Thank you for the comment and update. This was very helpful