Understand WebAssembly in 5 minutes
WebAssembly joined HTML, CSS and Javascript as a web standard on December 5, 2019. This will be useful for many things, and in terms of performance, it’s something never seen before in a browser. If you’ve got five minutes, I need to explain the little revolution that’s going on.
Once upon a time
In 1995, Javascript was created within 10 days by Brendan Eich. And at that time, Javascript was not designed to be fast. It’s basically for form validation and it’s slow like crazy. As time went by it got better.
In 2008, Google came out of nowhere and put on the table its new browser: Google Chrome. Inside Chrome was a Javascript engine called V8. And the revolution of V8 was the Just in Time (JIT) compilation of Javascript. This change from interpreted code to JIT compilation monstrously accelerated the performance of Javascript, and thus of browsers in general. This speed was going to allow the birth of technology like NodeJS or Electron and the explosion of popularity of Javascript.
In 2015, WebAssembly is announced for the first time with a small demo of a game running under Unity. The game runs directly in the browser!
In 2019, the W3C made WebAssembly a new web standard. Just as the V8 engine was in its day, WebAssembly is shaping up to be the new performance revolution. So WebAssembly is already here, and it’s off to a flying start.
What is WebAssembly?
WebAssembly, abbreviated to wasm, is a way to use non-Javascript code and run it in your browser. This code can be C, C++, Rust and many others. It will be compile and run in your browser at near native speed on your CPU. This code is in the form of a binary file that you can use directly from Javascript as a module.
WebAssembly is not there to replace Javascript. On the contrary, these two technologies are made to work together. By using the Javascript API you can load WebAssembly modules into your page. This means that you can take advantage of the performance of compiled code via WebAssembly with the flexibility of Javascript.
The name WebAssembly is a bit misleading. WebAssembly does indeed work for the Web, but it is not limited to it! The team that made WebAssembly has gone to a lot of trouble to make it generic so that it can be used everywhere. We’re starting to see examples of this.
Also, there’s a misconception that comes up all the time. WebAssembly is not a programming language. WebAssembly is an intermediate format, a bytecode, which acts as a compilation target for other languages. Okay, it’s not clear, let’s make some drawings.
How does it work?
Did you see that? Another work of art. Do you believe me if I tell you I use Photoshop? Anyway !
- Step 1 : It’s you and your developer skills. You produce source code in C, C++ (you can use others languages). This code is supposed to fix a problem or make a process too intensive for Javascript in the browser.
- Step 2 : you will use Emscripten to do the translation. Emscripten is a tool chain, built with LLVM, that will compile your source code into WebAssembly. You can install it and compile whatever you want in a few quick steps, we’ll look at it later. At the end of this step, you will have a WASM file.
- Step 3 : You will use the WASM file on your web page. If you come from the future, you can load this file like any ES6 module. Right now, the usage is slightly more complex, but nothing fancy.
OK, let’s get our hands dirty.
Show me the code
First of all, we need a small piece of C++ code to compile. Where some people will offer you the whole Diablo 1 game in the browser as an example, I’ll keep it simple with a function that adds two digits. We’re not going to prove the speed of C++ with that, it’s for the example.
int add(int firstNumber, int secondNumber) { return firstNumber + secondNumber; }
Then go to the Linux distribution of your choice. We will start by downloading and installing emscripten.
# installing dependencies (yes, you can use newer version of python) sudo apt-get install python2.7 git # gettin emscripten via a git clone. git clone https://github.com/emscripten-core/emsdk.git # downloading, installing and activating the sdk cd emsdk ./emsdk install latest ./emsdk activate latestl source ./emsdk_env.sh # make sure the installation worked emcc --version # compiling the c++ file to a webassembly template emcc helloWebassembly.cpp -s WASM=1 -o helloWebassembly.html # we serve the HTML and look at the result emrun helloWebassembly.html
That was the hackerman way of doing the wasm. There’s a simpler way.
You can go to this site and put your C++ code on the left. Then you get the name of the exported function in the WAT part. Using the add function code showed before i got : “_Z3addii” as function name, we’ll use that just after. You just have to click on download and you will get your WASM file back. Easy !
Now we can make WebAssembly work directly in the browser without all the annoying noise around.
<html> <head> <title>WASM test</title> <link rel="stylesheet" href="/stylesheets/style.css" /> </head> <body> <script> const getRandomNumber = () => Math.floor(Math.random() * 10000); WebAssembly.instantiateStreaming( fetch("https://012q1.sse.codesandbox.io/wasm/add.wasm") ) .then(obj => obj.instance.exports._Z3addii) .then(add => { document.getElementById("addTarget").textContent = add( getRandomNumber(), getRandomNumber() ); }); </script> <h1>Résultat du C++</h1> <p id="addTarget"></p> </body> </html>
This is it. This html web page allows you to use C++ compiled into WebAssembly ! I skip all the HTML and obvious stuff to go directly to line 11 with the InstantiateStreaming function. As the Mozilla documentation says, this function allows you to compile and instantiate our WebAssembly module via a simple fetch.
Then, I use the add function via the function name we retrieved earlier and use it to replace a piece of DOM. And voila ! C++ via Javascript inside your browser. How crazy is that? Look, I even made you a codesandbox with a working demo. I’m embedding it right here, play with it !
You’re gonna tell me it’s complicated just to do this, and you’re right. They’re working to replace the instantiation javascript bit with a simple import into the future. So be patient, it’s coming.
Epilogue
We’ve already been talking for five minutes, so I’ll stop here. If you want to know more about WebAssembly and you have time in front of you : i recommend this excellent article to go deeper in the subject. For the rest of the story, I’m looking forward to what this opening of the Web to other languages will bring. There’s a lot of potential and i can’t wait for the web to get even faster !
Nice article!
Super simple, merci.
Great article