What is WebAssembly (WASM)?

22/01/2019

Reading Time: 6 minutes

WebAssembly (abbrev. WASM) is a newborn web standard that developed by W3C Community Group. The first release -v1.0- has shipped in major browser engines (Microsoft Edge, Firefox, Safari and Google Chrome). Also, WebAssembly is the first new language to be fully supported in every major browser since Javascript.

WebAssembly is a low-level binary format that was created for native-like high performance, less memory usage, and portability to different platforms. It can be created with C/C++ and Rust now. Also, other programming languages -like C#- are on the road for that. Actually, now, C# is in the crawling period for modularity (short description is in the rest of the article).

Caution! WebAssembly isn’t opponent of Javascript.

Yes! WebAssembly is enough to create a complete web application, like Javascript. But they can be perfect couple for high-performance with minimum effort. Because they are strong in different spots.

Performance

As I said at the beginning, WebAssembly is a newborn standard for the web. Its performance increasing day by day.

Don’t miss out the latestCommencis Thoughts and News.

Performance

As I said at the beginning, WebAssembly is a newborn standard for the web. Its performance increasing day by day.

Don’t miss out the latestCommencis Thoughts and News.

Why we need WebAssembly?

As you know, the processes that like video & music editing, signal processing, and 3D rendering need high-speed calculation and high performance. Optimal CPU and GPU usage are very important for that. Right here, WebAssembly is joining the game. WebAssembly that developed with other languages, that is better than Javascript for all process described above.

Even faster startup time — Liftoff Compiler

As you know, V8 is the Google’s open source high-performance javascript and web assembly engine that was developed in C++. With this compiler, startup time is faster than before (TurboFan is the older engine).

Liftoff avoids the time and memory overhead of constructing an IR and generates machine code in a single pass over the bytecode of a WebAssembly function.

web assembly

On the other hand, Mozilla team working hard to speed-up webassembly performance. Their last browser performance statistics that was published are in the following.

web assembly

Threads

WebAssembly supports threads for the web such as Pthreads. In this way, you can use more than core from CPU (OS manages it) and you can running process in parallel. Threads are the part of the web workers.

What is a Web Worker?

The web worker is the browser independent javascript that can be running on background. Every worker is working on a CPU core, therefore, UI process performance is not affected. You can access WASM libraries there, and you can do big “things” with less performance loss.

Please don’t forget! Some features are in the beta versions of the browsers. For example, Liftoff engine is available since Chrome 69, Thread support is available since Chrome 70 (when flags updated as Enable).

Streaming Compilation

WebAssembly supports streaming compilation. What’s that? WebAssembly modules can be partially loaded. You can import WASM files in a specific location at a specific time as you want like in the following example. In this way, you don’t need importing modules from initialization. you can develop an application that has a faster startup time.

//main.js

var importObject = {
   env: { rand: arg => console.log(arg) }
};
WebAssembly.instantiateStreaming(
   fetch("util.wasm"),
   importObject
).then(obj => {
   obj.instance.exports._Z9factoriali(3)
});

The properties that highlighted as bold are important spots from above. But before applying that we should understand the WAT.

What is WAT?

WAT is the textual representation of the WASM, which called WebAssembly Text Format. You can update WASM files from WAT and vice versa. But, we need a tool for that. I’m using WasmExplorer to generate WASM and WAT from C/C++.

Now, we can explain the highlighted properties.

Converted “Util.c” file is in the following.

//util.c
#include <stdlib.h>
#include <time.h>
int factorial(int number)
{
  if (number > 1)
  {
    return number * factorial(number - 1);
  }
  else
  {
    return 1;
  }
}
int randomizer(int min, int max)
{
  return (rand() % (max - min + 1)) + min;
}

Generated “Util.wat” file is in the following(sliced, the original file is too long from that).

(module
 (type $FUNCSIG$i (func (result i32)))
 (import "env" "rand" (func $rand (result i32)))
 (table 0 anyfunc)
 (memory $0 1)
 (export "memory" (memory $0))
 (export "_Z9factoriali" (func $_Z9factoriali))
 (export "_Z10randomizerii" (func $_Z10randomizerii))
 (func $_Z9factoriali (; 1 ; ) (param $0 i32) (result i32)
  (local $1 i32)
  (local $2 i32)
  (set_local $2
   (i32.const 1)
  )
  ...

If you want to use streaming compilation, you need WAT file like that. In the following, I try to show you how to create importObject for instantiateStreaming.

env (Util.wat Line 3) -> env (main.js Line 2)

rand (Util.wat Line 3) -> rand (main.js Line 2)

_Z9factoriali (Util.wat Line 7) -> _Z9factoriali (main.js Line 9)

If you want, you can use _Z10randomizerii function (Util.wat Line 8).

But, don’t worry, there is an easier way from above 🙂

Emscripten

Emscripten is a toolchain for compiling to asm.js and WebAssembly, built using LLVM, that lets you run C and C++ on the web at near-native speed without plugins.

Emscripten installing instructions are here.

You can generate WASM and JS file with emscripten CLI tool and you can import js file to your page easily. You need some little updates to util.c file for that.

//util.c
#include <stdlib.h>
#include <time.h>
#include <emscripten/emscripten.h>
int main(int argc, char **argv)
{
   srand(time(NULL));
   printf("UTIL.wasm loaded.\n");
   return 0;
}
int EMSCRIPTEN_KEEPALIVE factorial(int number)
{
   if (number > 1)
   {
      return number * factorial(number - 1);
   }
   else
   {
      return 1;
   }
}
int EMSCRIPTEN_KEEPALIVE randomizer(int min, int max)
{
   return (rand() % (max - min + 1)) + min;
}

The util.c file will be converted to WASM and JS file within the following command.

[Definition]
emcc <C/C++ File path> -s WASM=1 -o <Output File Path>
[Example]
emcc ./module/util/util.c -s WASM=1 -o util.js

This command will generate “util.wasm” and “util.js” files. After that, the rest is easy 🙂

You will import “util.js” as a script and use exported functions, like that. All functions will be in “window” object.

<script src="util.js"></script>
<script>
   _randomizer(minValue, maxValue);
   _factorial(value)
</script>

I created a page with this method, you can see below. “UTIL.wasm loaded.” message will appear from the “main” function from WASM. And, you can use exported functions in time that you want.

Of course, these aren’t all methods for using WebAssembly. Other import techniques like wasm-loader are available. wasm-loader is the binary file loader for webpack. There isn’t any performance statistics for that yet but it is important to see feasibility.

Portability — Flexibility

Portability is a design goal of the WebAssembly community. They aim to use the third party libraries, a library that developed for other platforms and same library for cross platforms. And, they did it. We can use most of the libraries for the web.

Blazor

Blazor is an experimental .NET web framework using C# and HTML that runs in the browser.

As I said at the beginning, C# is in the crawling period. Why? Because As I understand, we can’t export a module that developed by C# yet. At least, it is not yet available officially. But If you want to start development on the Blazor, you can do it. It is similar to MVC Razor syntax.

On the other hand, some popular libraries are not available yet -like System.Generics-. You can use some limited features.

Who is using?

Some big products are there.

Did you notice something?

All of them need rendering something and need high performance for processes. Therefore, you should think well to use or not use.

Conclusion

As you know, we hear some new technologies, libraries, compilation methods, bundlers, frameworks every day. Generally, these are developed to increase performance for front-end technologies. WebAssembly is one of them. Maybe, the best one of them. But for what?

According to my personal opinion, WebAssembly usage statistics will stay at low levels for a long time. But, the reason isn’t bad. Actually, most of the web applications don’t need high performance, multiple threads or something like this. For example, I think a blog site like Medium never needs or as far as I can see, youtube.com doesn’t use yet, maybe it will never use. On the other hands, Maybe Pixlr Online Photo Editor or some Online Video Converter sites should use this technology.

References