What is WebAssembly? The Next Generation Web Platform Explained

0

For two decades, we have only had one programming language available to use natively in a web browser: JavaScript. The slow death of third-party binary plugins has excluded other languages, such as Java and Flash ActionScript, as first-class citizens for web development. Other web languages, like CoffeeScript, are simply compiled into JavaScript.

But now we have a new possibility: WebAssembly, or Wasm for short. WebAssembly is a small, fast binary format that promises near-native performance for web applications. Additionally, WebAssembly is designed to be a build target for any language, JavaScript being just one of them.

With all major browsers now supporting WebAssembly, it’s time to start thinking seriously about writing client-side applications for the web that can be compiled as WebAssembly.

It should be noted that WebAssembly applications are not intended to replace JavaScript applications, at least not yet. Instead, think of WebAssembly as a companion to JavaScript. Where JavaScript is flexible, dynamically typed, and delivered through human-readable source code, WebAssembly is fast, strongly typed, and delivered through a compact binary format.

Developers should consider WebAssembly for performance-demanding use cases such as gaming, music streaming, video editing, and CAD applications. Many web services have already taken the plunge, such as Google Earth. Figma, a collaborative drawing and diagramming application, turned to WebAssembly to reduce load times and execution speed, even when WebAssembly was relatively new.

How WebAssembly Works

WebAssembly, developed by the W3C, is in the words of its creators a “compilation target”. Developers don’t write WebAssembly directly; they write in the language of their choice, which is then compiled into WebAssembly bytecode. The bytecode is then executed on the client, usually in a web browser, where it is translated into native machine code and executed at high speed.

WebAssembly code is supposed to be faster to load, parse, and execute than JavaScript. When WebAssembly is used by a web browser, there is always the overhead of downloading the Wasm module and configuring it. For larger Wasm projects, these modules can run over several megabytes, so these delays can be significant. But all things being equal, WebAssembly runs faster.

WebAssembly also provides a sandboxed execution model, based on the same security models that currently exist for JavaScript. Wasm applications cannot directly access anything outside of the sandbox, including the DOM of the web page they are running on. Any interaction with the rest of the machine should use ABIs such as WebAssembly System Interface (WASI). WASI provides controlled access to files, network, system clock, and other system services often needed in programs.

Currently, running WebAssembly in web browsers is the most common use case, but WebAssembly is intended to be more than a web-based solution. The Wasmer project runs WebAssembly applications on the server side, much like the Node.js runtime runs JavaScript outside of the browser.

WebAssembly use cases

The most basic use case for WebAssembly is as a target for writing in-browser software. Components compiled in WebAssembly can be written in a number of languages; the final WebAssembly payload is then delivered via JavaScript to the client.

WebAssembly was designed with a number of performance-demanding, browser-based use cases in mind: gaming, music streaming, video editing, CAD, encryption, and image recognition, to name a few. name a few.

More generally, it is instructive to focus on these three areas when determining your particular use case for WebAssembly:

  • High-performance code that already exists in a targetable language. For example, if you have a high-speed math function already written in C and you want to embed it in a web application, you can deploy it as a WebAssembly module. Less performance-critical, user-facing parts of the application can remain in JavaScript.
  • High performance code that needs to be written from scratch, where JavaScript is not ideal. Previously, one could have used asm.js to write such code. You can still do that, but WebAssembly positions itself as a better long-term solution.
  • Porting a desktop application to a web environment. Many tech demos for asm.js and WebAssembly fall into this category. WebAssembly can provide a substrate for more ambitious applications than a simple graphical interface presented via HTML. See the WebDSP and Windows 2000 in-browser demos for two examples.

If you have an existing JavaScript application that does not exceed performance limits, it is best left alone at this stage of WebAssembly development. But if you need this application to go faster, WebAssembly can help.

WebAssembly language support

WebAssembly is not meant to be written directly. As the name suggests, it’s more like an assembly language, something the machine consumes, than a high-level, user-friendly programming language. WebAssembly is closer to the intermediate representation (IR) generated by the LLVM language compiler framework, than it is like C or Java.

So most scenarios for working with WebAssembly involve writing code in a high-level language and turning it into WebAssembly. This can be done in one of three basic ways:

  • Direct compilation. The source is translated into WebAssembly using the language’s own compiler toolchain. Rust, C/C++, Kotlin/Native, and D now all have native ways to emit Wasm from compilers that support those languages.
  • Third Party Tools. The language does not have native support for Wasm in its toolchain, but a third-party utility can be used to convert to Wasm. Java, Lua, and the .Net family of languages ​​all have support like this.
  • WebAssembly-based interpreter. Here, the language itself is not translated to WebAssembly; instead, an interpreter for the language, written in WebAssembly, executes code written in the language. This is the most cumbersome approach, as the interpreter can contain several megabytes of code, but it allows existing code written in the language to run virtually unchanged. Both Python (via PyScript, for example) and Ruby have translated interpreters in Wasm.

WebAssembly Features

WebAssembly is still in its infancy. The WebAssembly toolchain and its implementation remain closer to proof of concept than production technology. That said, WebAssembly custodians aim to make WebAssembly more useful through a series of initiatives:

Garbage collection primitives

WebAssembly does not directly support languages ​​that use reclaimed memory models. Languages ​​such as Lua or Python can only be supported by limiting feature sets or by embedding the entire runtime environment as a WebAssembly executable. But work is underway to support reclaimed memory models, regardless of language or implementation.

Threading

Native threading support is common to languages ​​such as Rust and C++. The lack of threading support in WebAssembly means that entire classes of WebAssembly-targeted software cannot be written in these languages. The proposal to add threading to WebAssembly uses the C++ threading model as one of its inspirations.

Mass storage and SIMD operations

Mass memory operations and SIMD (single instruction, multiple data) parallelism are essential for applications that shred stacks of data and need native CPU acceleration to avoid throttling, such as machine learning or scientific applications. Proposals are on the table to add these features to WebAssembly via new operators.

High-level language constructs

Many other features envisioned for WebAssembly correspond directly to high-level constructs in other languages.

  • Exceptions can be emulated in WebAssembly, but cannot be implemented natively through WebAssembly’s instruction set. The proposed scheme for exceptions involves exception primitives compatible with the C++ exception model, which in turn could be used by other languages ​​compiled into WebAssembly.
  • Reference Types make it easier to pass objects used as references to the host environment. This would make it easier to implement garbage collection and a number of other high-level functions in WebAssembly.
  • Tail callsa design pattern used in many languages.
  • Functions returning multiple valuesfor example via tuples in Python or C#.
  • Sign extension operators, a useful low-level mathematical operation. (LLVM also supports these.)

Debugging and profiling tools

One of the biggest problems with transpiled JavaScript was the difficulty of debugging and profiling, due to the inability to correlate transpiled code with source. With WebAssembly we have a similar problem, and it’s handled the same way (source map support). See the project note on the planned tool support.

Copyright © 2022 IDG Communications, Inc.

Share.

Comments are closed.