Update: With the upcoming Tauri 2.0, this is non-issue.
This repo is a small benchmark between Tauri's readBinaryFile
api and an alternative way, using base64 encoding rather than json, to transfer binary data from tauri's rust backend to web frontend.
It seems like the fs#readBinaryFile
api uses serde
to serialize Vec<u8>
data to a json string, then sends the string to javascript. Javascript deserializes the data to a js Array<number>
, and then uses Uint8Array.from(arr)
to convert it to a Uint8Array
. This approach doesn't sound efficient.
IIRC, the tauri team said it's not possible for now to transfer binary data directly due to some linux limatations. So, how about using base64 encoding to encode the binary data to string rather than json?
The benchmark test the fs#readBinaryFile
api and 3 other functions which do the same thing as readBinaryFile
: read a binary file and send the data to the frontend. The input is a 3.3 Megabyte png image from Unplash. The result shows how much time it takes from the js calling the invoke
/readBinaryFile
function till an ArrayBuffer
data is available.
default
: a direct call offs#readBinaryFile
base64
: rust side sends base64 encoded string and js side usesatob
andstring.charCodeAt
to get theArrayBuffer
base64-fetch
: same asbase64
, but js side usesfetch
api to decode.base64-manual
: same asbase64
, but js side manualy decodes (implementation from MDN) base64 strings.
We ran each method 50 times and calc the average(in release build).
Method | Time |
---|---|
default |
2859.31 ± 510.70 ms |
base64 |
531.00 ± 147.48 ms |
base64-fetch |
598.67 ± 126.60 ms |
base64-manual |
564.75 ± 126.70 ms |
It looks like using base64 encoding in this situation is much faster(around 5 times) than using json. For the base64 variants, althrough atob
returns a string rather than an arraybuffer, it's still slightly faster than the manual javascript implementation.