Introducing WebAssembly
In this section, we will look at how WebAssembly works. One way of running Blazor is by using WebAssembly, but for now, let's focus on what WebAssembly is.
WebAssembly a binary instruction format that is compiled and therefore smaller. It is designed for native speeds, which means that when it comes to speed, it is closer to C++ than it is to JavaScript. When loading JavaScript, the JS files (or inline) are downloaded, parsed, optimized, and JIT-compiled; most of those steps are not needed when it comes to WebAssembly.
WebAssembly has a very strict security model that protects users from buggy or malicious code. It runs within a sandbox and cannot escape that sandbox without going through the appropriate APIs. If you want to communicate outside of WebAssembly, for example, by changing the Document Object Model (DOM) or downloading a file from the web, you will need to do that with JavaScript interop (more on that later, and don't worry – Blazor will solve this for us).
To get a bit more familiar with WebAssembly, let's look at some code.
In this section, we will create an app that sums two numbers and returns the result, written in C (to be honest, this is about the level of C I'm comfortable with).
We can compile C into WebAssembly in a few easy steps:
- Navigate to https://wasdk.github.io/WasmFiddle/.
- Add the following code:
int main() { return 1+2; }
- Press Build and then Run.
You will see the number 3
being displayed in the output window toward the bottom of the page, as shown in the following screenshot:
WebAssembly is a stack machine language, which means that it uses a stack to perform its operations.
Consider this code:
1+2
Most compilers (including the one we just used) are going to optimize the code and simply return 3
.
But let's assume that all the instructions should be executed. This is the way WebAssembly would do things:
- It will start by pushing
1
onto the stack (instruction: i32.const 1
), followed by pushing2
onto the stack (instruction: i32.const 2
). At this point, the stack contains1
and2
. - Then, we must execute the add-instruction (
i32.add
), which will pop (get
) the two top values (1
and2
) from the stack, add them up, and push the new value onto the stack (3
).
This demo shows that we can build WebAssembly from C code. Now, we have C code that's been compiled into WebAssembly running in our browser.
Other languages
Generally, it is only low-level languages that can be compiled into WebAssembly (such as C or Rust). However, there are a plethora of languages that can run on top of WebAssembly. Here is a great collection of some of these languages: https://github.com/appcypher/awesome-wasm-langs.
WebAssembly is super performant (near-native speeds) – so performant that game engines have already adapted this technology for that very reason. Unity, as well as Unreal Engine, can be compiled into WebAssembly.
Here are a couple of examples of games running on top of WebAssembly:
- Angry Bots (Unity): https://beta.unity3d.com/jonas/AngryBots/
- Doom: https://wasm.continuation-labs.com/d3demo/
This is an amazing list of different WebAssembly projects: https://github.com/mbasso/awesome-wasm.
This section touched the surface of how WebAssembly works and in most cases, you won't need to know much more than that. We will dive into how Blazor uses this technology later in this chapter.
To write Blazor apps, we must leverage the power of .NET 5, which we'll look at next.