With the start of a new year, it’s common to reflect on what happened over the past year and plan for the upcoming year. In this article, I’m going to look at the state of WebAssembly in 2020 and where I see things going this year.
Before we jump in, for those of you who may be unaware of what WebAssembly is, I’ll give you a quick primer.
What is WebAssembly?
WebAssembly, which you might also see abbreviated as Wasm, is a low-level assembly-like language that is designed to be safe, fast, compact, portable, and a compilation target.
That’s a bit of a mouthful but, basically, it’s not designed to be written by hand. You use a higher-level language and compile to it.
The files are designed to be as small as possible so that they can be transferred and downloaded quickly. They’re also structured in such a way as to optimize validation and parsing so that the module can start up as quickly as possible.
From the beginning, the desire was to be able to use WebAssembly modules outside the browser as well but the initial work was in the browser. Regardless of where they’re used, you need to know that a malicious module won’t compromise your system. WebAssembly modules don’t have access to anything out of the box. Even memory is simulated by using an ArrayBuffer that’s passed to it by the host.
A few years ago, all the major browser makers got together and decided to implement an MVP of WebAssembly that they then released in 2017. You can use WebAssembly in Safari, Chrome, Firefox, Edge and in mobile browsers like iOS Safari, Firefox for Android, and Chrome. Because Node.js is built with the V8 engine of Chrome, you can run WebAssembly modules there too.
Because WebAssembly isn’t limited to the browser, in 2019 a new standardization effort called WASI (WebAssembly System Interface) was formed to define a standard and secure way for WebAssembly to work outside the browser. Lin Clark wrote a good article explaining WASI if you’d like to learn more.
Since the release of the MVP, work has continued with improved performance and new features. At the same time, the number of places where you can use WebAssembly modules outside the browser has increased. Also, right at the end of 2019, a major milestone happened when the specification for the MVP became a W3C recommendation.
Now that you know what WebAssembly is, what were some of the milestones in 2020?
WebAssembly isn’t just in the browser. There’s a lot going on in a lot of different spaces including Edge and Serverless computing, IoT, smart contracts, and using modules in your own code to name a few so this will be more of an overview rather than an in-depth review.
Several WebAssembly features arrived this year including Reference Types, bulk memory operations, the ability to import and export functions with 64-bit integer parameters, as well as the re-enabling of the SharedArrayBuffer in Firefox desktop.
The SharedArrayBuffer is used by WebAssembly to share memory between threads. Unfortunately, in January 2018, the Spectre/Meltdown attacks forced browser makers to disable the buffer until they could find a safe way to re-enable it.
Google Chrome was the first to re-enable the buffer in its desktop browser by using site isolation. Since then, the industry has opted to use the COOP (Cross-Origin-Opener-Policy) and COEP (Cross-Origin-Embedder-Policy) response headers as a solution to re-enable the buffer. Firefox desktop was the first browser to use this approach.
Aside from the WebAssembly features themselves, some other noteworthy events included the WebAssembly version of Google Earth officially going public and the announcement that the Firefox browser itself is using WebAssembly to sandbox its own C++ code rather than rewriting it.
When the world went into lockdown due to COVID-19, most people needed to adjust. Meetings still needed to happen, for example, so many turned to video conferencing platforms like Zoom. WebAssembly has played a role here too. For example, Zoom uses WebAssembly in its web client to avoid using WebRTC and Google Meet uses it for its Machine Learning in their MediaPipe.
In April, the Uno Platform announced preview support for Visual Studio Code, building on its previous support for WebAssembly introduced in 2018. Also in April, Node.js introduced experimental WASI support.
In May, Blazor WebAssembly became official when it shipped as part of .NET 3.2 allowing C# developers to target the web with Single Page Applications. Over the following months, a number of improvements were made to .NET and Mono that benefited both Blazor WebAssembly and the Uno Platform with the release of .NET 5. If you’re a C# developer who wants to code for the web using C#, keep an eye on this space as there’s a lot going on here!
2020 had its ups and downs and, in what looked like a blow to WebAssembly and WASI, Mozilla’s cutting of 25% of its workforce seemed pretty negative. Fortunately, it appears that most of the engineers were scooped up and will continue to advance the web. In fact, from what I understand, the entire WASI team are now at Fastly. Mozilla will now focus on WebAssembly in the browser and Fastly will take over the out-of-the-browser projects that were started at Mozilla including WASI and the Wasmtime runtime.
So, with 2020 behind us, what’s in store for 2021?
What’s expected in 2021
One area that I see movement this year is with the re-enabling of the SharedArrayBuffer in browsers. As a nice start for the year, Google Chrome 88 for Android was released and will become available on Google Play over the next few weeks making it the first mobile web browser to re-enable the buffer via the COOP and COEP response headers.
Work is also progressing on re-enabling the buffer in Safari and in Firefox for Android.
An important note here is that, starting with Google Chrome desktop version 91, the COOP and COEP response headers will be required to enable the buffer. If you currently use the SharedArrayBuffer, or plan to use it, I highly recommend updating your server’s settings to include these headers. If you don’t think you can make the adjustments in time, you can register for the reverse origin trial to maintain the current desktop behavior until Google Chrome 93.
There are a number of WebAssembly proposals in the works with some that are expected this year including Module Linking and Interface Types.
The intent of the Module Linking proposal is to make linking two or more modules at run-time declarative. Rather than a developer writing code to manually pass the exports from one module as the imports to another, which is time consuming and error prone if one of the modules is modified, the idea is that the WebAssembly engine can handle connecting them together and possibly even optimizing them.
The Interface Types proposal will help with communication between modules or the host. This is because WebAssembly modules only natively support four data types (32-bit integers, 64-bit integers, 32-bit floats, and 64-bit floats). Boolean values are represented using a 32-bit integer but all other data types used by your code need to be represented in your module’s linear memory. The trick is, one programming language may represent something one way and another language may represent it in a different way. If two or more modules are going to work together, especially if they’re not written in the same languages, you need some way to map things and that’s where the Interface Types proposal comes in. The Interface Types proposal allows a toolchain to describe the module’s high-level values so that other modules, or the host itself, can communicate using high-level values.
When working on a project, sooner or later, you need to debug the code to track down an issue. Initially, debugging a WebAssembly module was very limited. You could log messages to the console or you could step through the module’s WebAssembly text format representation in the browser’s developer tools. Later, source maps were introduced by Emscripten (Emscripten is a WebAssembly compiler toolchain for C and C++) so that you could see your code as you were debugging it but, under the hood, it was still just stepping through the text format version of the code so it wasn’t the greatest experience. Source maps were also not widely supported by other toolchains.
Over the past year, work has been underway to improve the WebAssembly debugging experience in browsers by implementing the DWARF debugging format. DWARF was chosen because it’s already supported by many languages. I expect debugging will continue to advance this year as the WebAssembly toolchains improve their DWARF support.
“UI for WebAssembly”
The Uno Platform worked closely with Microsoft and the online community over the past year to improve .NET and the Mono runtime which helped the C# community see major performance improvements regardless of if they were using the Uno Platform or Blazor WebAssembly. Work didn’t stop with the release of .NET 5 and I believe we’ll see additional tooling and performance improvements for C# developers who are targeting the web by the release of .NET 6 in November. C# developers have two great choices when creating a compelling browser UI using WebAssembly and their favorite programming language.
WebAssembly has a very vibrant ecosystem with a lot of people and organizations working on improving it. If you’d like more information on WebAssembly itself, you can check out this GitHub list of repositories for the meetings, proposals, and specification to name a few: https://github.com/WebAssembly
Similarly, if you’re interested in what’s happening outside the browser with WASI, the following GitHub repository is a good place to start: https://github.com/WebAssembly/WASI
A lot of the WebAssembly community can also be found on Discord: https://discord.gg/2RDb7vCez3
Guest blog post by Gerard Gallant, the author of the book “WebAssembly in Action” and a Senior software developer / architect @dovico