Mad Science With WebAssembly

This article provides a short background of WebAssembly and provides a tutorial to get you started.

Background

“Write once, work everywhere” is the beauty of the web. This cannot be said for the many native platforms, including iOS, OSX, Android, Windows, Gnome, and other. Just remember the last time you tried compiling or installing something and it would just work! Nothing beats npm i && npm start 😂 .

But the high-level environment that the browser offers comes at the cost of performance. “Write once, work everywhere” also means that the web can't be broken. Providing a high-level also means that developers are stuck with the API's that the browser has. Want truly multithreaded apps? Too bad. You're stuck with WebWorkers and will have to wait until the Web API's or ES6 standards change. Want to build a graphics intensive app

Or at least this was the case.

WebAssembly is what changes all of that.

What is WebAssembly?

In short, Webassembly (wasm) is a binary format for the web that aims to match native performance, extend the JavaScript language (kernel semantics). For a more in-dept explanation, refer to the sources at the end of this article. Check out an Angry Bots and compare the differences between asm.js and wasm performance.

Possibilities

Some practical use cases of wasm include migrating the bottlenecked parts of a JavaScript application to wasm and importing them as scripts (very similar to node c++ bindings):

// vDOM reconciliation in react
import diff from 'wasm-diff'

// Check if react update the DOM
function reconcileDOM(vDOM, html) {
    diff(vDOM, html)
}

wasm can also be used as a compile target for games, video editing, and other native applications.

At the moment, this is pretty difficult. I've been messing around with wasm but haven't found any tutorials to help me out so I thought I would shed some light on how to get started.

Mad Science

First, let's try to compile a native application so that we have something to compare wasm to. We will be using, openFrameworks a mature graphics library that supports compilation to wasm through emscripten, build tool which compiles C/C++ to wasm. I should note that this tutorial assumes that you are running on macOS. If you are using another platform, please reference the docs.

First, we'll need to go to openframeworks and download the version for osx. Preferably, you should move this to your projects directory. (Note: Avoid cloning from the github repo)

Then we need to generate the files needed to run the openFrameworks examples, located in of v0.9.x_osx_release/examples. To do this, open projectGenerator.app inside of projectGenerator-osx. If you don't prefer manually entering the path to the download, click on the search icon and open the openFrameworks folder.

The result should resemble this:
openFrameworks setup wasm demo

Cool! Now click generate. This should notify you to open xCode. When it opens, click on the 'scheme' at the top right and select the library icon:

xcode setup wasm demo

Perfect! Now, cd to the examples/3d/3DPrimitivesExample directory inside of v0.9.x_osx_release, open 3DPrimitivesExample.xcodeproj, and click xCode's 'play' button.

You should see something similar to this:
openFrameworks examples demo

Impressive! Now let's see how well wasm performs.

==Requirements: cmake, git, node ==

To get started, we'll need to download the emscripten sdk and 'Portable Emscripten SDK for Linux and OS X'. After unzipping the folder:

# Move it to your mode directory.
mv emsdk_portable ~/

# cd into it.
cd ~/emsdk_portable

# Fetch the latest registry of available tools.
./emsdk update

# Download and install the latest SDK tools.
./emsdk install latest

# Make the "latest" SDK "active"
./emsdk activate latest

# Set the env variables for the current session
source ./emsdk_env.sh

Requirement: Your default browser should support WebGL

Now that we have emsdk, let's use it to compile an openFrameworks project. Inside the same terminal window, cd back to the examples/3d/3DPrimitivesExample directory inside of v0.9.x_osx_release and run:

# This will take a while. Come back after a cup of coffee
emmake make

# Run the demo in your default browser
emrun bin/3DPrimitivesExample.html

"...wth... HOW?" Alon Zakai (creator of emscripten) explains this well:

This blog post is a work in progress. I am in the process of asking Alon Zakai about how to migrate asm.js code to wasm and will update this blog post when I get the answer


I do not have a comments system at the time of writing this so feel free to email me if you have any questions (amilajack@gmail.com).

Sources/Recommended Reading:

Amila Welihinda

Autodidact. Open Sourcerer. Lover of the web, JS, and OSS. Working to improve DX for the web platform.

Subscribe to Open Sourcery

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!