Using Rust+WASM inside a React Frontend App

Hello,

I have used rust-webpack-template to generate my POC project :

What I want to do is to delegate some heavy tasks to Rust and WASM.
Tasks like array filter, sort, map, ... and also async.

In my POC project I tried a first basic thing : filter an array using native JS and filter using Rust+WASM (js call Rust function).
Inside Rust, I used js_sys.

However, I find that native JS filter is more faster than Rust+WASM :

JS :

Rust + WASM Code :
https://github.com/helabenkhalfallah/rust-react-wasm-js/blob/master/src/lib.rs#L24

Result (chrome) :
Call to JS filter took 0.05499999679159373 milliseconds.
Call to Rust collect_numbers took 2.219999994849786 milliseconds.

Result (safari) :
Call to JS filter took 0 milliseconds.
Call to Rust collect_numbers took 4.999999999999886 milliseconds.

Result (firefox) :
Call to JS filter took 0 milliseconds.
Call to Rust collect_numbers took 4 milliseconds.

I tried, an array length 10, 100 and then 452, but always JS is more faster.

Have I missed up a configuration in my project ? Is there a particular recommendation (api, config, a way to do, ...) ? In which cases (Rust + WASM + JS) are recommended ?

Thank you so much for your help :sunny: :sunny:

These arrays are very small, and the filtering logic is very simple. I think in this case it's to be expected that doing it in JS is much faster compared to having to call some external code and incurring whatever overhead associated with doing so. If the array length was in the thousands, tens of thousands or more, and the filtering logic was complex, I could see the WASM solution being faster. I think you have the right idea to do heavy tasks in WASM, but the task in this example is very light.

1 Like

Hello @Heliozoa aha, okay, I will try with more complexe logic and more big data, thank you so much !

Hello @Heliozoa, now I tested with an array having 5000 & 10000 elements.
Operations :

  • sort by id
  • map (transform)
  • filter id > 200

5000 elements :
Call to JS map took 2.0650000078603625 milliseconds.
Call to Rust WASM transform_me took 489.1749999951571 milliseconds.

10000 elements :
Call to JS map took 4.765000005136244 milliseconds.
Call to Rust WASM transform_me took 964.559999993071 milliseconds.

Data :
https://github.com/helabenkhalfallah/rust-react-wasm-js/blob/master/js/pages/MockData.js

JS :
https://github.com/helabenkhalfallah/rust-react-wasm-js/blob/master/js/pages/UserListPage.jsx#L48

Rust :
https://github.com/helabenkhalfallah/rust-react-wasm-js/blob/master/src/lib.rs#L72

Generally in frontend these are the expensive parts : map a big backend response, filter, sort, ..

JS is always faster, I feel confused about when WASM is more faster and how it can help me to have better performance ?

Thank you :sunflower:

Arrays in general are allocated pretty quickly as it's just a contiguous block of memory, and the allocation time between something like length 8 vs length 8k is not likely to matter much in the grand scheme of things if only done once or a couple of times.

Try more complex data, e.g. composed of various nested types (each of which must be instantiated separately), or something much more computationally expensive.

Okay, I will try, but in a real case, I don't think that in frontend side we do something much more computationally expensive, this will be the role of Backend or BFF (like graphql). I don't see very well the added value of WASM in frontend side.

I will try async part : calling async http from Rust vs from JS.

Thanks.

Here's an example of a pretty cool Wasm project to showcase what it's capable of: idTech 4 WebAssembly port - Doom 3 Demo
If you're only doing things that are already normally taken care of by the frontend the value of Wasm is probably not that high. One thing to consider is that you could potentially move some of the computation done in the backend to the frontend and lighten the load on the server.
A good comparison might be parallelism: it can provide a big speedup in some cases, but in simple cases the overhead just ends up slowing the entire thing down.

This is a very very good point ! I will compare the both approach !

Super ! I try !

Thank you so much for these ideas, very very clear ! :sunflower: :sunny:

Hello, just for information, I tried async http calls.
Number of records returned by the server about 7800 records.

  • Rust + reqwest
  • JS + axios

jsRequestSocials took 280.15000000596046 milliseconds.
wasmRequestSocials took 772.1000000019558 milliseconds.

Even if I duplicated, JS always more faster.

I also paralysed 3 requests, JS still faster.

Another issue, I have a big WASM file, about 2.2 MO :

I have done only some frontend usual tasks, if I choose to move some backend parts inside frontend, I will have a very huge bundle that will take tooooooo long time to be downloaded especially for devices with some poor performances. :flushed: :pleading_face:

Yeah I loved safety when using Rust + WASM (everything is check before frontend consumption) but I will loose performance.

I don't think that Rust + WASM are suitable for frontend apps that doesn't do 3D, image/video processing, VR, ... Even for these apps we should compare to see the added value.

Thank you so much for all your answer and contribution. I understand now very well when WASM and when not !

May be you hadn't open the opt. In rust, opt is the key. Try this :

https://rust-embedded.github.io/book/unsorted/speed-vs-size.html

Hello, using rust-webpack-template had a default optimization configuration :

https://github.com/helabenkhalfallah/rust-react-wasm-js/blob/master/Cargo.toml#L17

LTO is good for optimization :
https://stackoverflow.com/questions/52291006/why-does-using-lto-increase-the-size-of-my-rust-binary

https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html

But in spite the wasm file is huge (2.2MO).

Thanks.

I think, for website use case, WASM will not shine, JS still the faster.

I will try another types of applications like these :
https://webassembly.org/docs/use-cases/

Thank you.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.