Master Blazor WebAssembly on .Net6
Did you know that it is possible to create “vanilla” WebAssembly projects in .Net6? Yes, it is possible! Although it is not officially supported, the new Blazor WebAssembly SDK is flexible enough to allow you to build pure wasm projects.
This is extremely useful in many scenarios where you just want to build a web client application but leverage all the power of WebAssembly for high-demanding algorithms using .Net. Here at the Plain Concepts Research Team, we have developed a set of samples that illustrates multiple “hidden” functionalities that you can do with WebAssembly on .Net6, to cover the most common use cases for high-performance applications. We can even use the debugger in Visual Studio 2022!
- 1 What is Blazor WebAssembly?
- 2 Where does Blazor WebAssembly run?
- 3 Authentication in Blazor WebAssembly
- 4 What are the components of Blazor?
- 5 Blazor vs. React or Angular
- 6 Vanilla wasm project
- 9 Use the Virtual File System
- 10 Production: Brotli/Gzip compression
- 11 Final notes
What is Blazor WebAssembly?
Where does Blazor WebAssembly run?
As Microsoft explains, with Blazor WebAssembly, the client application and its dependencies are compiled into binary code and downloaded in parallel to the web browser. When a user accesses the application, it runs very quickly in the browser the end user uses, because, thanks to WebAssembly, the code is highly optimized.
Authentication in Blazor WebAssembly
Microsoft describes on its website how to secure a standalone Blazor WebAssembly application using the Blazor WebAssembly authentication library.
Thus, when an application is designed for individual user accounts, it instantly receives a reference from Microsoft.AspNetCore.Components.WebAssembly.Authentication package. With this, users can be verified, and tokens can be obtained.
What are the components of Blazor?
In Blazor, a component is a tool used to create what the end user sees. For example, in a web page, it would be the home page, another one of its URLs, one of the drop-down elements…
Razor components can be used in Blazor applications, automatically making them Blazor components. Razor is a .NET based code syntax for creating web pages and uses extensions such as .cshtml or .razor.
Blazor vs. React or Angular
Blazor, React, and Angular are all open-source frameworks. Blazor uses C#, while React and Angular use TypeScript. The former is from Microsoft, while React was created by Facebook and Angular was created by Google.
Using one or the other depends on the developer’s needs: the programming language he prefers, the developer community behind it (React and Angular are older than Blazor)… But there is no doubt that with Blazor, it is very easy to use all the power of WebAssembly to create web applications that take advantage of all the system’s resources.
Vanilla wasm project
First of all, for every web assembly project, you will need a csproj that uses .net6 framework, the Microsoft.NET.Sdk.BlazorWebAssembly SDK to enable the wasm targets, and the references to the WebAssembly and DevServer nugets. Additionally, we need to add a Program.cs static class with a Main method that creates the host builder, and a wwwroot folder with an index.html file that calls blazor.webassembly.js entrypoint. Finally, to print something to the console, you could just call Console.WriteLine in the main method. To enable the debugger, a lauchSettings.json with “inspectUri” property needs to be in the properties folder.
If it feels a little messy don’t worry, you will understand it much better looking at the console sample. You can just use this sample as your default WebAssembly template. Another easy way would be just to create a Blazor WebAssembly App from Visual Studio 2022, and then delete all razor files and remove from Program.cs the lines that add RootComponents and scoped services.
Once that everything is in place, put a breakpoint on Program.cs and run the debugger using the name of the project profile, or the IIS Express profile (we recommend the first as it seems to be faster). Your web app will stop in the breakpoint at the .Net6/WebAssembly code!
Although this flexibility is great, it comes with a price: It is rather slow. Check the next section to know more.
The functionality available in the above samples is great but it is not enough to build high-performance applications. For example, when you add an event listener which callback needs to access js properties and methods, multiple calls between js and .net are performed every time it is triggered. This is especially harmful on events that trigger often, like “mousemove”.
To solve this, like many other problems like interacting with native browser libraries like WebGL, OpenAL or WebXR, the best option here is to create a custom C++ or Rust library and then call them using P/Invoke.
Check the console-native example to know how to compile a C++ library using emscripten, that also makes a callback to .Net very fast.
This is the most optimum way to work with the browser, but its architecture is a bit more complex. We recommend keeping the JSRuntime wrapper for no real-time algorithms, like initializations or sporadic events, and leave the native libraries approach for the rest, like operations that occur inside a draw loop.
Use the Virtual File System
Fortunately, we have implemented a VFS system that instructs your web assembly application to load the files described at your csproj into the virtual file system, to be used later by your app seamlessly. Check it out the source code at the filesystem sample.
Production: Brotli/Gzip compression
Load times are very important in every app. As you probably know, in web apps file size is critical to load time. The Blazor WebAssembly SDK targets already allow us to compress our web assets using GZip or Brotli, but it doesn’t provide an out-of-the-box solution to serve those files when the client asks for them.
Fortunately, we found a simple solution: Create an “empty” ASP.net server and configure it to serve compressed files automatically when a compressed version of a file exists in the server. Check the full source code at the filesystem-server sample.
We hope you find these samples useful and helps you boost your wasm apps. All this work is framed in the efforts made to bring WaveEngine to .Net6 in web. With these building blocks, we were able to render with WebGL at a great performance, as well as other technologies like OpenAL or WebXR. The samples repositories already have a WebXR sample that we are using as a sandbox for testing the technology, and maybe soon we will add WebGL and OpenAL ones in a new article. Keep posted to know more!