In this article, I’m going to take the same approach that I used last year to show you the current state of WebAssembly. I’ll look at the big events of the past year and then try to predict where I think things are going in 2022.

2021 in Review

This past year turned out to be a much bigger year for WebAssembly than I was expecting, especially around the Safari web browser.

Safari

When the MVP of WebAssembly was released back in 2017, Safari was right there with the same features as the rest of the browsers. In the years that followed, Safari unfortunately fell behind.

Over 2021, I was very pleased to see a lot of work put into Safari to bring its WebAssembly support up to date. As of the Safari 15.2 release on December 14th, some of the features added to Safari over 2021 include:

SharedArrayBuffer

WebAssembly uses the SharedArrayBuffer to share memory between WebAssembly threads. Unfortunately, the buffer needed to be disabled until a secure solution could be found for the Spectre and Meltdown vulnerabilities.

Chrome desktop was the first to re-enable the buffer by using site isolation as a workaround to the vulnerabilities. Since then, the COOP/COEP response headers were created as a way to tell the browser to create an isolated environment in order to securely re-enable the buffer.

Firefox desktop was the first to use these response headers to re-enable the buffer in 2020.

Early in 2021, Chrome desktop was adjusted to come into alignment around the new standard and it now requires the COOP/COEP response headers if you want to use the buffer.

Also in early 2021, Chrome for Android received support for the response headers allowing WebAssembly threads on mobile devices. With that, and Safari’s recent re-enabling of the buffer, all modern browsers except for Firefox mobile, now support WebAssembly threads.

I expected the response headers to be added to Firefox mobile during 2021 as well. Unfortunately, that didn’t happen but it looks like they’ll arrive in early 2022.

Fixed-Width SIMD

SIMD (Single Instruction, Multiple Data) is a type of parallel processing where the same operation is performed on multiple points of data simultaneously. This can have large performance improvements for things like image processing by taking advantage of a CPU’s SIMD instructions.

There are multiple types of SIMD so, as a starting point, it was decided to go with Fixed-Width 128-bit SIMD operations.

Chrome and Firefox added Fixed-Width SIMD support in May and June respectively. This feature isn’t yet in Safari.

Exception Handling

Up until now, exception handling wasn’t part of WebAssembly so applications that throw exceptions needed to include additional code and leverage JavaScript to fill the void. Building that logic into your module resulted in larger code sizes and reduced performance so it was generally recommended that modules not use exceptions unless they absolutely had to.

Exception handling was officially released by Chrome in September. Much to my surprise, as mentioned earlier, Safari implemented exception handling in December as part of Safari 15.2.

This feature is not yet available in Firefox or Node.js but is being worked on in both.

According to the release notes from V8 (the JavaScript engine of Chrome and Node.js), the code size in their test dropped by 43% compared to the JavaScript implementation of exception handling. Their code saw a 9% size increase compared to not having any exception handling but the WebAssembly exception handling had no performance impact. When using the JavaScript implementation, they were seeing a 30% performance impact compared to no exception handling.

The V8 release notes around the WebAssembly exception handling can be found here if you’re interested: https://v8.dev/blog/v8-release-95#webassembly

Module Linking and Interface Types

The Module Linking proposal is about making the linking of two or more modules declarative and letting the WebAssembly runtime handle the linking process for you at run-time.

The Interface Types proposal relates to how modules will be able to interact with each other by describing their high-level data types. For example, one module may use UTF-8 strings while another uses UTF-16. By describing their data types, the WebAssembly runtime will be able to facilitate the communication between the modules.

I expected these two proposals to be ready in 2021. Progress is being made but they’re still in the works.

.NET 6

Over the past year, a lot of work has gone into improving .NET’s WebAssembly support, tooling, and performance. With the .NET 6 release in November, one of the bigger features added was AOT (Ahead of Time) compilation.

.NET code is typically compiled part of the way to native code into an intermediate language (IL) similar to how WebAssembly works. With a normal .NET deployment, the IL code is then compiled the rest of the way on the target device using just-in-time compilation.

When it comes to running client-side in the browser, the .NET WebAssembly runtime itself is WebAssembly code but your app’s files are IL code. The IL code gets interpreted as it runs which isn’t as performant compared to if your code would get compiled.

With AOT, your app’s .NET code is compiled to WebAssembly. This allows for better performance in exchange for larger file sizes compared to the IL interpreted versions. The larger files may also result in longer download times the first time your code is accessed.

As a middle ground between having only IL code or having everything AOT compiled, the use of Profile-Guided AOT is also possible. With this approach, significantly used portions can be compiled using AOT, while the rest keeps running with the IL interpreter.

The Uno Platform also introduced a feature called XAML Resource Trimming which works with the AOT compilation to remove unused code. With this, they saw a 50% reduction of their WebAssembly application’s size in their tests.

The Bytecode Alliance

The Bytecode Alliance is a group originally formed by Intel, Mozilla, Red Hat, and Fastly with the goal of building a secure platform that can run untrusted code on any platform, device, or OS by leveraging standards like WebAssembly and WASI.

WASI (WebAssembly System Interface) is a standardization effort for WebAssembly’s use outside the browser in a secure and consistent way. Lin Clark wrote a good article explaining WASI if you’d like to know more: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/

The desire from the beginning was for more organizations to join the alliance but the internal structure of the group needed to be adjusted to allow it to scale. When it came time to create the foundation, Red Hat stepped out and Microsoft stepped in to help the rest of the founders incorporate the group as a nonprofit organization. In 2021, the alliance was able to expand and now includes Microsoft, Google, Arm, DFINITY Foundation, Embark Studios, Shopify, and University of California at San Diego.

Aside from championing WASI, the alliance is also the source of projects like Wasmtime, Cranelift, Lucet, WAMR, and Enarx.

If you’re interested, more information about the Bytecode Alliance can be found here: https://bytecodealliance.org/

Where is WebAssembly being used?

Every year we see more commercial products add WebAssembly support. In 2020, for example, products like Zoom, Google Meet, Google Earth, and the Firefox browser itself joined the ranks of products that use WebAssembly like Cloudflare Workers for serverless computing, eBay’s barcode scanner, the AutoCAD web app, and the Unity gaming engine to name a few.

2021 was no exception and the following are some of the new areas where you’ll now find WebAssembly

As the features and tooling improve, and as more and more commercial products embrace WebAssembly, we’re starting to see WebAssembly’s use in frameworks and on the general web. It’s still a small segment but it’s nice to see that growth is happening: https://almanac.httparchive.org/en/2021/webassembly.

2021 turned out to be a great year for WebAssembly so what can we expect in 2022?

About Uno Platform
For those new to Uno Platform – it allows for creation of pixel-perfect, single-source C# and XAML apps which run natively on Windows, iOS, Android, macOS, Linux and Web via WebAssembly. Uno Platform is free and Open Source (Apache 2.0) and available on GitHub.

Expectations for 2022

One of the things that I think will happen in 2022 is the rounding out of features that are in almost all areas now. One feature I expect is exception handling.

Exception Handling

This is a major feature needed by a number of programming languages so it’s high on the priority list of items being worked on. It’s already in Safari, Chrome, and Edge and is being worked on in Firefox and Node.js.

Because the less-performant JavaScript version still works, if you have modules already using exceptions, you can use the more efficient version in the areas that support WebAssembly Exception Handling and fallback to the JavaScript version in the other locations for now.

SharedArrayBuffer

As mentioned earlier, almost all modern browsers on both desktop and mobile now support the COOP/COEP response headers including Firefox desktop. These response headers allow the browser to securely enable the SharedArrayBuffer which in turn allows your modules to use WebAssembly threads.

The remaining modern browser that doesn’t yet support these response headers is Firefox mobile but they’ve been added to version 97 which is due to ship in February 2022.

Fixed-Width SIMD

My guess is that this feature will be implemented in Safari this year.

My reasoning is based on the amount of WebAssembly support added to Safari over 2021, that the WebAssembly Fixed-Width SIMD specification is now standardized, and that Xcode (Apple’s development environment for their OSes) supports SIMD.

Tail Calls

Tail calls are needed by some programming languages in order to support WebAssembly. In some cases, workarounds are possible but slower. Tail calls are also useful for things like compilation optimizations and certain forms of control flow.

This proposal has been complete for some time now but can’t move to phase 4 until at least two web VMs implement it (Chrome, Firefox, or Safari). Chrome has implemented this behind a flag but isn’t planning on shipping it until it reaches phase 4 so we’re still waiting on one more web VM to add support.

It’s not that the other vendors don’t want to implement this feature but everyone’s busy so they’ve focused on the items that they feel have the highest priorities. There is talk right now where people are trying to make the case to move this higher in the list of priorities.

Multiple Memories

This proposal would allow a module to have more than one block of memory.
One use case for this is that a module could use one block of memory for its internal data while passing another block to other modules that might have been written by someone else. This way, you can prevent your module’s internal data from getting corrupted if the other module writes things wrong. It also allows a module to keep sensitive data separate from the shared data.

Another use case for this is with WebAssembly threads where you could share a block of memory with your own threads while keeping the rest of the module’s data in a different block of memory.

There are a number of other use cases defined with the proposal if you’re interested in learning more: https://github.com/WebAssembly/multi-memory/blob/main/proposals/multi-memory/Overview.md

This proposal is in phase 3 and has lots of compelling use cases so I’m hopeful that it’ll make it into production this year.

WASI

Earlier in this article, I mentioned that the Module Linking and Interface Types proposals were expected in 2021. Unfortunately, the two proposals weren’t completed as I hoped but they’re still in the works.

Although those proposals are part of WebAssembly itself, they’re features that are needed to create something that’s being referred to as the Component Model. Based on the FAQ page, the Component model is similar to an OS’s process model that defines how processes start up and communicate with each other. WASI’s role is similar to the operating system’s APIs.

Work is continuing with the Component Model and WASI despite waiting on the Interface Types proposal. If you’re interested, you can see a list of WASI proposals here: https://github.com/WebAssembly/WASI/blob/main/docs/Proposals.md

In Conclusion

Over the past year we saw several WebAssembly features that can be used to improve performance like the SharedArrayBuffer for use with WebAssembly threads, Fixed-Width SIMD, and exception handling. WebAssembly support was improved in .NET 6 and both .NET and the Uno Platform added AOT performance improvements.

Safari was a big surprise in 2021 where they did a lot of work on catching up to the other browsers’ WebAssembly support.

In 2021 we saw more commercial products join the ranks of those that use WebAssembly and we saw that WebAssembly is starting to be used on the general web.

It looks like 2022 will be another good year for WebAssembly with certain features likely making it into production in the final areas that don’t support them yet.

There are a number of interesting feature proposals in the works for WebAssembly itself and the Bytecode Alliance will continue working on features that will help WebAssembly expand its use outside the browser.

If you’re interested in seeing where things are with regards to WebAssembly feature support, the following website can help. The first column even shows you how the browser you’re using stacks up: https://webassembly.org/roadmap/

To get started with Uno Platform we recommend using our official onboarding tutorial which walks you through building your first app in less than 5 minutes. You can also read more about Uno Platform for WebAssembly here.

Thank you to guest blogger Gerard Gallant, author of “WebAssembly in Action”  and a Senior software developer for writing another comprehensive article on the current and future state of WebAssembly.

Tune in Today at 12 PM EST for our free Uno Platform 5.0 Live Webinar
Watch Here