WebAssembly: Finally Freed from JavaScript?

Written By David Ackerman

Most of us love to hate JavaScript, the software famously developed in 10 days by Brendan Eich.

If someone has only good things to say about the language, they probably haven't used it enough yet. I mean, there are definitely good parts, but if your language needs a book like that, it means there are a lot of bad parts.

The web is an undeniably useful and ubiquitous platform for just about anything these days, and JavaScript is the only real standardized programming language for us to use. The language is getting better and more performant every year, but as with any programming language, it's not always the right tool for the job.

Unfortunately, it is often the only tool for the job.

So, what can we do if we want to use a different programming language instead?

Before you start learning up any new skill or concept, I suggest you take a look at my course “10 Steps to Learn Anything Quickly”.

Transpilation vs. Compilation

A programming language is really just a human-friendly syntax. We already have programs that interpret or compile that syntax into something a computer can run. Instead of compiling our program into machine code, we could compile it into another programming language.

This process is known as transpilation because it's converting one programming language to another. It lets programmers write code in their favorite language, then rely on the transpiler to turn it into JavaScript, which the browser can execute on the web page.

This isn't a particularly new idea, and there are several programming languages that transpile into JavaScript; two notable ones being ClojureScript (Clojure to JavaScript) and Google Web Toolkit (Java to JavaScript).

Compilation vs. Transpilation
Compilation vs. Transpilation

The problem is that JavaScript was not designed to be transpiled at all.

It is a garbage collected language with very loose semantics that, while more friendly for beginning developers to learn, is really bad as a transpilation target.

JavaScript is Too Dynamic

When you create a class in JavaScript, you can give it fields and methods just like other object-oriented programming languages. Normally, an interpreter could read a class definition and allocate some storage for the fields based on what type they are, and therefore predict how much space is needed.

By predicting how much space is needed and laying out objects in memory efficiently, the interpreter or compiler can optimize the code execution. This works well in programming languages like C, or Java, because you can't change what fields a class has, or their types after you define it.

Not so with JavaScript!

Because JavaScript is a very dynamic language, you can add/remove and modify variables at run-time, even changing a field from a Number to a String halfway through.

For instance, in the below code, you can see that we can modify fields on class instances and even completely change the methods even after the objects are created!

Most browsers these days will attempt to optimize JavaScript code by assuming that classes won't change, but if that assumption is broken, they have to fall back to much slower, but more general algorithms for executing the code. They can never rule out the possibility that the user will invoke obscure and complicated features of the language at any point, which causes additional interpreter complexity and slowdowns in speed.

If JavaScript was less dynamic, it would be easier to optimize and less complicated to make other programming languages transpile into it.

In fact, because of this, attempts have been made to define a subset of the JavaScript language so browsers could pretend certain invariants are upheld (like not changing a class dynamically, and not making a variable change types).

This language is known as asm.js.

Asm.js is a More Optimized Subset of JavaScript

JavaScript

Asm.js is a restrictive subset of the JavaScript programming language meant to be compiled to.

It doesn't have any of the frills of JavaScript, but because it is a subset of the language, it can still be run by regular JavaScript browsers. The functionality it supports is a lot more like C code, and you specify the types of your arguments in certain ways.

For instance, in JavaScript, a number is always a double-precision floating point value, which is really inefficient if you want integers. In asm.js, you can signal to the interpreter that you want an integer by writing x = x|0;. This is still valid JavaScript code (doing a bitwise OR on any number with zero just returns the same number), but it lets asm know it can use fast integer math.

Here's an example of what asm.js code looks like if it was written by hand (it looks much crazier when machine generated).

Since it's still valid JavaScript, regular browsers can run it with identical behavior to the compiled version. Browsers that support asm.js can make extra optimizations and run much faster (like Firefox).

The downside is that it's really a hack on top of JavaScript. It's a text-based format, so it takes a long time to parse, and there are many syntactic contortions necessary to make it compatible with JavaScript—so it's hard to reach native (i.e. C-like) speeds.

Enter WebAssembly.

WebAssembly is a Compile Target for the Web

Java Script

WebAssembly is a low-level language format explicitly designed to be compiled to by other programming languages. We've been talking about transpilation this whole time, but since WebAssembly is sufficiently low-level compared to JavaScript, we could really call it compilation.

And the best part—it's not being designed in 10 days!

It is based on asm.js, but the spec is being built from the ground-up to be an efficient and general-purpose compile target. It is not a subset of JavaScript, so it doesn't need to make contortions to support being run by old engines.

Here's an example of some WebAssembly code in textual format. The main format is binary, but it can be freely converted to a text format more suitable for reading by humans. This is just one potential text syntax, as the official format hasn't yet been decided.

It's Fast

WebAssembly is a binary format.That means it's much more compact than JavaScript or asm.js, making it faster to download. It's also built to be extremely fast to parse (in fact, in some early benchmarks, it's 20x faster than regular JavaScript!). This is especially awesome for mobile devices, which are battery and CPU constrained.

Because it doesn't have to be a subset of JavaScript, it doesn't have garbage collection. This means code written in C and C++ that manage memory manually can run directly in native speeds without any built-in GC trying to get in the way, and other programming languages are free to implement their own custom garbage collector. (Note that an optional built-in garbage collector is also planned at some point.)

It will also support hardware-accelerated features of modern processors like Single Instruction, Multiple Data (SIMD). This would let you write code that could potentially do a calculation on multiple variables at the same time, really speeding up certain applications like live video processing or games.

Last, but not least, it will even eventually support multithreading, which is something that is simply not possible in JavaScript.

It's Safe

Since it is built for the web, it will be safe to run in browsers from day one. What does “safe to run in browsers” mean?

For one, it's memory safe, which means you can't crash your computer just by going to some website with an allocation bug.

Secondly, code will have to abide by the existing browser-based security restrictions like the same-origin policy to prevent malicious sites from stealing user's data without their permission.

It's Portable

Lastly, WebAssembly will be portable, so there are no platform specific aspects of the format. This means it can run on many different devices including regular web browsers, mobile, or even Internet of Things (IoT) devices. Technically it doesn't even have to run in the context of a webpage!

And just because WebAssembly won't have platform specific aspects, a given host may decide to provide additional APIs on top of what's available normally. For instance, if Android had a native host for WebAssembly, it could provide an API to access native Android features that aren't normally available to websites.

This is Great for Other Programming Languages

What does all this mean for you?

It means we'll have a solid platform for optimizing lower level code, and a great vector for implementing programming languages that run in a cross-platform way. Among other things, it makes other programming languages first-class citizens of the web.

Because there isn't a built-in GC, and the overhead will be minimal, any language under the sun can be compiled. We can think of the web as a new operating system, capable of running on any device imaginable—and now we don't have the limitations of JavaScript to worry about!

There are already communities forming around languages like ClojureScript, but I can see higher-performance languages really starting to become mainstream.

Will we Kill JavaScript?Java Script

So the big question is, since JavaScript was created in 10 days and has lots of haters, does this mean everyone will jump ship once other languages are available?

JavaScript has a lot of momentum behind it, so it’s not going anywhere. It will likely continue being the dominant language on the web, for many years to come.

Despite how much people like to bash it (myself included), there have been many improvements in the last couple years, thanks to EcmaScript 6. It will always be a great language when you want high flexibility and fast prototyping, or the most choices for frontend work.

However, if you want to build something like a video encoder, security encryption software, or need to carefully manage memory, now you can use a low-level language suited to the task.

Or if you really care about catching bugs at compile time, you could use something that is statically typed with a fancy type system like Haskell. You could even theoretically mix them in a single app.

It's Still Early Days

So where is WebAssembly now?

It was first announced in June 2015, and as of writing this post (May 2016), it's still being designed. However, they have been hard at work, and already there's a spec and reference interpreter, a draft of the binary format, and even a playable 3D game by Unity called “angry bots” compiled from C++. Everything is open source, so you can check out their implementations and designs in the github repos.

We should all feel excited to be living in a time with this kind of innovation and potential. The web has already proven to be the most useful and accessible platform ever, and WebAssembly will take everything to the next level.

I'm extremely excited for what the future brings. Long live the web!