If you've been keeping up with the latest developments in the .NET world over the past year or two, you've probably heard the word Blazor mentioned once or twice. Blazor is a new client-side UI framework from theASP.NET team. Its big selling point is the ability to write rich web UI experiences using HTML, CSS, and C# instead of JavaScript—something a lot of developers have been dreaming of.
While JavaScript has been the defacto standard for front-end web development since its inception, we’ve never really seemed to be happy with it. I mean, how many superset or transpile to JavaScript languages have sprung up over the years to help improve JavaScript and make it more maintainable? CoffeeScript, Dart, Elm and Scala—to name but a few.
Looking at the most loved languages, TypeScript, a language designed by the legendary Anders Hejlsberg, tops the list. The same man who designed C#, no less. It adds features such as interfaces, classes, compile time type-checking, even generics. However, all those features and more already exist in C#, and have done for years. C# is a powerful, flexible, feature rich language that is easy to learn.
But Blazor has already started to show it has potential as a highly efficient and productive programming model outside of its original design—as a direct competitor to JavaScript single page application (SPA) frameworks.
Microsoft already has multiple experiments going on with Blazor, trialling it with desktop applications using Electron and WebWindow (an experimental lightweight alternative to Electron). But most recently, for native mobile app development where the Blazor programming model is mixed with native Xamarin forms controls.
Could we be seeing the start of a single unified UI framework for building any type of application with .NET, be it web, desktop, or mobile? I don't know about you, but I certainly find that an exciting prospect.
What makes Blazor so flexible?
To answer this question, we need to understand how Blazor has been architected.
Essentially, Blazor has a separation between how it calculates UI changes (app/component model) and how those changes are applied (renderer). This sets Blazor apart from other UI frameworks such as Angular or ReactJS/React Native that can only create web technology based UIs. By using different renderers Blazor is able to create not only web based UIs, but also native mobile UIs as well.
This does require components to be authored differently, so components written for web renderers can’t be used with native mobile renderers. However, the programming model is the same. Meaning once developers are familiar with it, they can create UIs using any renderer.
Render/Hosting Model
At its core, Blazor's app/component model is responsible for calculating UI changes, but you can use different renderers to control how the UI is actually displayed and updated. These renderers are more commonly referred to as hosting models. At the time of writing, there are four hosting models for Blazor in various stages of development.
Blazor Server (Remote Renderer)
- Platform: Web
- Status - GA/Production Supported
Blazor WebAssembly (WebAssembly Renderer)
- Platform: Web
- Status: Preview (Committed Product)
Blazor Electron (Electron Renderer)
- Platform: Desktop (Windows, Mac, and Linux)
- Status: Experimental (Not Committed)
Mobile Blazor Bindings (MobileBlazorBindings Renderer)
- Platform: Mobile (iOS and Android)
- Status: Experimental (Not Committed)
Blazor Server is the only production supported model at the time of writing. Blazor WebAssembly is due for release around May 2020—I would expect this could be the big announcement at Build. Blazor Electron and Mobile Blazor Bindings are both marked as experimental and Microsoft hasn't yet committed to shipping these.
App/Component Model
This is the engine room of the framework. Here we can find all the non-UI specific elements which make Blazor work. The programming model, routing and navigation, and the render tree, which is Blazor's mechanism for calculating UI changes.
The part I want to focus on though is the programming model. Out of the four hosting models I talked about above, the first three have one thing in common, they all understand web standards. Components authored to target these hosting models will be using HTML and CSS. But the fourth model, Mobile Blazor bindings, doesn't understand web standards at all. Applications built for this hosting model will need to have their components written using native mobile controls.
To give a more visual example, let's look at the same component written for Blazor WebAssembly, which uses a web standards compliant renderer, vs Mobile Blazor Bindings, which uses the non-web standards-based renderer.
// WebAssembly Renderer
<div>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</div>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
// MobileBlazorBindings Renderer
<StackLayout>
<Label FontSize="30" Text="@($"Current count: {currentCount}")" />
<Button Text="Click me" OnClick="@IncrementCount" />
</StackLayout>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
It's easy to see the differences between the two code samples, but what I want you to focus on the similarities.
Both samples have a markup section and a code block. In fact, the code blocks are identical between the samples. They each have an `OnClick` event with a specified handler and both use expressions to output the value of the current count field.
The point I'm making here is the programming model is the same. And this is the power of Blazor, learn the programming model and, save a few tweaks here and there, you're going to be able to produce UI for any type of app, on any platform—that's something we've not been able to do before with .NET.
Now we have a bit more of an understanding about how Blazor is put together, I want to talk a bit about the two main hosting models, Blazor Server and Blazor WebAssembly.
Blazor Server
The Blazor Server hosting model is currently the only production supported option for Blazor development right now. It was released back in September 2019 with .NET Core 3, during .NET Conf.
In this model, the Blazor application runs on the server on top of the full .NET Core runtime. When the user loads the application a small JavaScript file is downloaded which establishes a real-time, two-way SignalR connection with the server. Any interaction that the user has with the app is then transmitted back to the server over the SignalR connection for the server to process. After the server is done, any UI updates are transmitted back to the client and applied to the DOM.
Now, I know what you're thinking. There is no way that that can be performant, all of those interactions and UI updates being constantly sent back and forth. But I think you'll actually be surprised.
The team did some load testing on Blazor Server to establish what it could and couldn't deal with and this is what they found.
Test 1 - Standard D1 v2 instance on Azure (1vCPU & 3.5GB memory)
The application could handle over 5000 concurrent active users without any visible degradation in performance.
Test 2 - Standard D3 v2 instance on Azure (4vCPU & 14GB memory)
The application could handle over 20,000 concurrent active users without any visible degradation in performance.
These are pretty impressive figures, I think you'll agree. The major findings which came out of these experiments were that memory and latency are the main bottlenecks of Blazor Server applications. If latency got above 200ms then performance took a hit and scale was limited by the available memory on the box.
Benefits
- Runs on the full .NET Core runtime
- Fast development cycle
- Small download size
- Code is kept on the server and not downloaded to the client
Drawbacks
- Doesn't work well in high latency environments
- No offline support—requires a constant connection to the server
- Heavy resource demand on the server
Ideal use case
I honestly think Blazor Server can be used for lots of scenarios, but its niche will be in intranet applications or low demand public-facing apps. The speed of development with this hosting model is obscenely quick, and I mean fast, due to everything being on the server. There is no need for separate API projects, for example, you can just consume application services directly in your components. I was sceptical of Blazor Server at first, but I have to say, I have been really surprised with what it can do.
Blazor WebAssembly
This is the big one, the hosting model that usually gets most interest, and for good reason. This model offers a direct competitor to JavaScript SPAs such as Angular, VueJS, and React.
By using WebAssembly, we are able to write our UI logic using C# and not JavaScript. It's currently in preview and due for release around May 2020.
A version of the Mono .NET runtime, compiled to WebAssembly, is downloaded to the client’s browser along with the application DLLs and any dependencies. Once everything is in the browser, the Mono runtime is bootstrapped, and it, in turn, loads and executes the application DLLs.
I'm going to address the first question that usually arises from hearing the above explanation, what is the download size? Well, the current preview weighs in at around 2.4mb, that's pretty impressive considering there’s a .NET runtime involved. But I appreciate that this isn't amazing when compared to some JavaScript frameworks. By the time the WebAssembly hosting model is released in May, the team hopes to cut that size significantly. The first prototype of Blazor used a very compact .NET runtime, which compiled to just 60k of WebAssembly code. I believe major size improvements are just a matter of time.
Currently, Blazor WebAssembly uses interpreted mode to load and run your application. In this mode, the Mono IL interpreter executes your applications .NET DLLs inside the browser. The only part of the process that is compiled to WebAssembly is the Mono runtime. In the future, the team are looking to allow developers to choose if their apps, or more likely parts of their apps, will be compiled to WebAssembly as well—This is known as AOT or Ahead Of Time compilation. The benefit of this mode is performance, the trade-off is a larger download size.
Benefits
- Compiles to static files, meaning there is no need for a .NET runtime on the server
- Work is offloaded from the server to the client
- Apps can be run in an offline state
- Codesharing, C# objects can be shared between client and server easily
Drawbacks
- Payload. Right now if you create a fresh new Blazor project, it weighs in at around 2.4mb. The team hopes to cut this down significantly come May.
- Load time. Due to download size, devices on poor connections can experience longer initial load times.
- Restricted runtime. Apps have to operate in the browser’s sandbox and are subject to the same security restrictions as any JavaScript application.
Ideal use case
Blazor WebAssembly is built to be a direct competitor to modern JavaScript frameworks. Therefore, anywhere you would be looking to use one of those frameworks, you could consider Blazor. It's also trivial to make Blazor WebAssembly apps into PWAs (Progressive Web Application). In fact, there will be an out of the box template for this coming in May.
It's also important to point out that using Blazor WebAssembly doesn't require you to use .NET on the server. Meaning if you have a backend written in Node, PHP, or Rails you can happily use Blazor as the frontend without any issues as Blazor WebAssembly compiles to static files.
What's the future of Blazor?
With one hosting model in production already and another on the way shortly, let's finish by turning our attention to the future.
Where do I see Blazor going? Coming back to my earlier thought around Blazor becoming a single UI framework for any .NET application. I think this is where Blazor is heading, in my opinion. If all of the current hosting models for Blazor move into production, and right now I can't see why they wouldn't, developers will have the option to learn a single programming model which they can use to create UIs anywhere. This is a big deal.
At a time where there are lots of discussions around the barrier for entry to .NET, with so many choices new developers to the platform have to face, Blazor could offer clarity when it comes to UI, a single programming model, learnt once and applied anywhere. For me, that's the hype with Blazor.