.NET Software Engineering

A deeper understanding of Blazor and WebAssembly

Mariekie
Coetzee

September 15, 2022

15

mins

Blazor was released in 2018, we all learned that it gives us all the benefits of a modern rich single page application (SPA) and the capability to use .NET end to end.

So how exactly did Microsoft manage to get a .NET app to run on a browser? Most blogs explains that it runs on WebAssembly (Wasm), but when they say WebAssembly I hear Javascript. So I decided to dig further to understand the concept.

WebAssembly

WebAssembly (WASM) provides a way to run code, written in multiple languages, on the web at near native speed. It is supported by modern web browsers, no plug-ins are required, and it provides features and major gains in performance.

We know what it provides but what is it...?

'Blazor University' answers this question the best:

Wasm is an instruction set that is formatted in a specific binary format. Any host (hardware or software) that adheres to this specification is therefore capable of reading binaries and executing them – either interpreted, or by compiling directly to machine language specific to the device.

Javascript is an interpreted language and does not get compiled like C#. An interpreter in the browser reads the JavaScript code, interprets each line, and runs it. Modern browsers use a technology known as Just-In-Time (JIT) compilation, which compiles JavaScript to executable bytecode just as it is about to run.

But how does C#  compile to Wasm specification? Well, Blazor sends Mono, compiled as WASM, down to the client. Then our unchanged dll files are executed within Mono.

What is Mono

Mono is a full .NET runtime that evaluates .NET assemblies. It offers different compilers and depending on which one is used, it will translate/compile our  .NET assembly and run our app!

A bit of history

Mono started when .NET framework was announced in 2000. This was when Microsoft published CLI as an open ECMA approved standard allowing developers to build independent implementations of .NET. A developer, Miguel de Icaza started creating his own Linux version of it. He later required a team of developers to ensure Mono stays relevant with new releases of .NET framework and later started his company called Xamarin. Microsoft purchased Xamarin in 2016 and after years of evolution Mono is able to run many .NET frameworks apps on many platforms.

There are a couple of interesting Mono Components:

Mono Components
  • C# Compiler
  • Mono Runtime: It implements the ECMA Common languages infrastructure. The runtime provides a:
    ◦ Just-in-Time(JIT) compiler and
    ◦ Ahead of Time (AOT) compiler,
    ◦ a library loader, garbage collector, threading system and interoperability functionality.
  • .NET framework Class Library - provides a comprehensive set of .NET framework compatible classes.
  • Mono Class Library - Includes Additional classes going above and beyond Microsoft Base Class Library.

Mono is not a Blazor technology, in fact it can even run on gaming consoles and some gaming engines:

With the popularity of C# more game engines started using .NET. The Mono runtime, now part of .NET 5, was a great choice because it was able to run C# code on many platforms including Android, iOS, PC, Mac, and Linux. Mono also supported dedicated game consoles like Xbox, PlayStation, and Nintendo platforms. Now with .NET including Mono with .NET 5, we are seeing some game engines getting ready to upgrade.

A software engineer wrote a great blog where he ran C# natively in the browser through web assembly via Mono-Wasm.

Interpreter mode

Blazor runs on the browser using .NET intermediate language (IL) interpreter implemented in WebAssembly, when AOT is not enabled. Mono runtime is compiled to WebAssembly but not .NET assemblies. The browser loads and execute Mono runtime which in turn loads and executes the .NET assemblies. It is slower than JIT on server side runtime because of the interpretation.

Just-In-Time (JIT) Compiler

The JIT compiler translates IL to machine code on demand, on the same machine that the code is running on. This means that the code is compiled while the app is running. JIT needs to balance out time spent on optimizing code against savings that the resulting code can be produced. This results in a slower experience.

Ahead-of-Time (AOT) compilation

AOT compilation will at build time, transform .NET assemblies to WebAssembly binaries, which means there is no interpretation. It runs as WebAssembly code! Some Mono runtimes are still required, but not all of it.

Blazor supports AOT and can be enabled by adding a <RunAOTCompliation> property set to true in the apps project file:


When AOT is not enabled Blazor will run apps in the browser using the interpreter compilation resulting in a much slower experience. AOT addresses the performance issue by compiling our code directly into WebAssembly which can be executed by the browser.

One disadvantage is that AOT compiled apps are larger than IL interpreted compilations. Therefor the initial download to the client will take longer for AOT compilations.

WebAssembly AOT compilation is only performed when publishing the app because the AOT compilation takes several minutes for small apps. The Release configuration ensure that the .NET Intermediate Language linking is also run to reduce the size of the app.

Please see the links below for great resources that formed part of my research on this topic.

Resources: 

https://blog.stevensanderson.com/2018/02/06/blazor-intro/
https://scientificprogrammer.net/2019/08/18/differences-between-mono-and-net-core/
https://www.mono-project.com/ https://tirania.org/monomac/
https://devblogs.microsoft.com/dotnet/choose-a-net-game-engine/

Next Article

Looking for a new challenge?

We’ve got ambitious plans to be the best Microsoft solutions company in Australia and New Zealand.