Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use WebAssembly (wasm) code in a Web Worker?

Currently, a Web Worker is instantiated thus:

let worker = new Worker('worker.js');

The browser then fetches worker.js and it can start responding to messages.

I'd like to implement my worker's functionality using WebAssembly. Ideally, I'd like to do something like this:

let worker = new Worker('worker.wasm');

But I'm pretty sure that's not possible. The most obvious alternative is to have worker.js fetch worker.wasm and compile and run it. But this means we fetch one script (worker.js) whose only job is to fetch and run another script (worker.wasm). This feels gross to me. And so my question: is there a cleaner way of using WebAssembly within a Web Worker, which won't introduce an extra fetch step?

like image 872
Josh Hansen Avatar asked Nov 02 '17 20:11

Josh Hansen


1 Answers

You can postMessage a WebAssembly.Module to a Worker. You'd therefore compile foo.wasm in your main script, and then postMessage it, which implementations are expected to optimize so as not to recompile or duplicate code (though at this time not all implementations do so). You then merely need your worker to instantiate.

One thing you need for instantiate is an importObject, and what you pass in needs to be resident to that worker! So even if you could say "new worker with this .wasm" you wouldn't have a way to specify the importObject.

This is documented in structured clone, which also affects IndexDB.

like image 145
JF Bastien Avatar answered Oct 13 '22 08:10

JF Bastien