What is WebAssembly?
WebAssembly Concepts
This article explains the concepts behind how WebAssembly works including its goals, the problems it solves, and how it runs inside the web browser's rendering engine.
What is WebAssembly?
WebAssembly is a new type of code that can be run in moden web browsers and provides new features and major gains in performance. It is not primarily intended to be written by hand, rather it is designed to be an effective compilation target for source languages like C, C++, Rust, C#, etc.
This has huge implications for the web platform — it provides a way to run code written in multiple languages on the web at near-native speed, with client apps running on the web that previously couldn't have done so.
What's more, you don't even have to know how to create WebAssembly code to take advantage of it. WebAssembly modules can be imported into a web (or Node.js) app, exposing WebAssembly functions for use via JavaScript. JavaScript frameworks could make use of WebAssembly to confer massive performance advantages and new features while still making functionality easily available to web developers.
WebAssembly goals
WebAssembly is being created as an open standard inside the W3C WebAssembly Community Group with the following goals:
- Be fast, efficient, and portable — WebAssembly code can be executed at near-native speed across different platforms by taking advantage of common hardware capabilities.
- Be readable and debuggable — WebAssembly is a low-level assembly language, but it does have a human-readable text format (the specification for which is still being finalized) that allows code to be written, viewed, and debugged by hand.
- Keep secure — WebAssembly is specified to be run in a safe, sandboxed execution environment. Like other web code, it will enforce the browser's same-origin and permissions policies.
- Don't break the web — WebAssembly is designed so that it plays nicely with other web technologies and maintains backwards compatibility.
How does WebAssembly fit into the web platform?
The web platform can be thought of as having two parts:
- A virtual machine (VM) that runs the Web app's code, e.g. the JavaScript code that powers your apps.
- A set of Web APIs that the Web app can call to control web browser/device functionality and make things happen (DOM, CSSOM, WebGL, IndexedDB, Web Audio API, etc.).
Historically, the VM has been able to load only JavaScript. This has worked well for us as JavaScript is powerful enough to solve most problems people have on the Web today. We have run into performance problems, however, when trying to use JavaScript for more intensive use cases like 3D games, Virtual and Augmented Reality, computer vision, image/video editing, and a number of other domains that demand native performance (see WebAssembly use cases for more ideas).
Additionally, the cost of downloading, parsing, and compiling very large JavaScript applications can be prohibitive. Mobile and other resource-constrained platforms can further amplify these performance bottlenecks.
WebAssembly is a different language from JavaScript, but it is not intended as a replacement. Instead, it is designed to complement and work alongside JavaScript, allowing web developers to take advantage of both languages' strong points:
- JavaScript is a high-level language, flexible and expressive enough to write web applications. It has many advantages — it is dynamically typed, requires no compile step, and has a huge ecosystem that provides powerful frameworks, libraries, and other tools.
- WebAssembly is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages with low-level memory models such as C++ and Rust with a compilation target so that they can run on the web. (Note that WebAssembly has the high-level goal of supporting languages with garbage-collected memory models in the future.)
With the advent of WebAssembly appearing in browsers, the virtual machine that we talked about earlier will now load and run two types of code — JavaScript AND WebAssembly.
The different code types can call each other as required — the WebAssembly JavaScript API wraps exported WebAssembly code with JavaScript functions that can be called normally, and WebAssembly code can import and synchronously call normal JavaScript functions. In fact, the basic unit of WebAssembly code is called a module and WebAssembly modules are symmetric in many ways to ES modules.
JavaScript Isn’t The Only Option Anymore
Great, so what does this mean for everyone? Well, while running DOOM 3 in a web browser is certainly a cool demo, it’s not exactly game changing.
Until now, JavaScript has been your only choice to make your web pages interactive. Whether you love it or hate it, it was never designed to be used like it is today. It was a scripting language designed to do trivial tasks like making dropdown menus animate, and over 25 years has been hacked together to run moden-day workloads. Only through the use of state-of-the-art JS engines and JIT compilation optimizations can it even be compared to native speeds.
And so, as web pages grew to become full web applications, JavaScript client frameworks like React, Vue, and Angular propped up to meet the demand. Of course, there are still server-side frameworks—you’re reading this from WordPress, a PHP framework—but client frameworks offer huge performance increases. With a client framework, the DOM is updated automatically after pressing a button or interacting with the app. Even realtime server-rendered frameworks must make a network request to change anything, and in the worst case, must refresh the entire page.
While all of the web’s frontend code is written in JavaScript, the backend code is often not. In high performance datacenter workloads, it’s often beneficial to use proper desktop languages like C#, C++, Rust, and Go. After all, these can literally save you money by requiring fewer servers to meet the same demand.
However, it also costs you money in development time, since now you have to deal with interoperability between your C# backend, and your JavaScript frontend. Simply not being able to share code, models, and libraries may increase your development complexity by up to 2x what it would be with a unified system. This reason alone is why NodeJS server backends are so popular, despite sounding like a terrible idea 20 years ago.
Having the ability to write C#, C++, Rust, and Go code that runs on the server and client would open the door to many more options, and remove the need for JavaScript as a programming language almost entirely. In the WASM client framework Blazor, JavaScript usage is reserved for interoperability with existing client packages, and basic scripting.
Summary
WebAssembly is only a few years old. It still has plenty of room to grow, and is still picking up speed. It’s not unreasonable that five years from now, frameworks like Blazor and Yew will be just as common as React, Angular, and Vue.
This could be argued to be fragmenting the web ecosystem, but WASM is cross platform. WAPM, a WASM package manager, may become the go-to way to share libraries between frameworks of different languages.
WebAssembly has a bright future. It has had a successful start in the browser ecosystem and is now headed for the cloud. It is a technology that augments other cloud native technologies and concepts such as Kubenetes, FaaS and Serverless.
This article has given you an short explanation of what WebAssembly is, why it is so useful, how it fits into the web, and how you can make use of it.
If you’re interested in how WebAssembly can work with your projects or startups, get in contact with us