The software development landscape is often an image of a rushing river more than a stalwart mountain. With the introduction of WebAssembly, many languages are working to implement their own solutions to this binary compilation target. For Microsoft, the solution is Blazor.
Blazor is a web framework designed to run client-side in the browser in a WebAssembly-based .NET runtime (Blazor WebAssembly) or Server-side on an ASP.NET Core application server (Blazor Server). WebAssembly is a low-level language with a compact binary code that languages can compile to and run in the browser with near-native performance. Razor pages are used as the primary language for generating the Blazor components being served to the browser. WebAssembly supports JavaScript Interoperability, which allows, in the case of Blazor, C# and JavaScript to run side-by-side and reference one another. Razor Components are Blazor’s solution for custom web components; these work very similarly to Angular and React.js components.
What Blazor Isn’t
Blazor is not a way for you to off load your entire application onto a client’s browser. Blazor Server isn’t much different than MVC is today. Blazor WebAssembly isn’t completely ready to roll today.
What Blazor Is
Blazor is a framework that allows a .NET developer to write code that can functionally compete with JavaScript frameworks like Angular, React.js, and Vue.js. Blazor is a framework Microsoft is investing in and has a detailed roadmap to take Blazor beyond the browser and onto Native UI. Blazor is an incremental replacement for JavaScript in your web application front-end.
Why Should I Care
Blazor allows .NET developers to write interactive front-ends to their applications without having to learn a new language. Blazor can be adapted from existing ASP.NET MVC applications. This is through the use of Razor pages and the JavaScript interoperability of WebAssembly.
Blazor and JavaScript Frameworks
Blazor and JavaScript frameworks (i.e. Angular and React.js) both use components to create a modular, reusable, and interactive single-page web application. Also, they both run on the browser and are downloaded as a complete package when the web application is navigated to. This means that all code can be read from the downloaded package and shouldn’t contain proprietary or sensitive code.
Blazor comes packaged with WebAssembly and a .NET runtime in the download, but JavaScript frameworks come only with any javaScript dependencies referenced by the project when downloaded. Blazor allows .NET and JavaScript to reference one another through WebAssembly.
Razor Component Example
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
[Parameter]
public int IncrementAmount { get; set; } = 1;
private void IncrementCount()
{
currentCount += IncrementAmount;
}
}
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<Counter IncrementAmount="10" />
Blazor and ASP.NET MVC
Blazor and ASP.NET MVC are frameworks created by Microsoft. Both use Razor pages, but the specific layout is different between the two.
MVC
@model MvcMovie.Models.MovieGenreViewModel
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-controller="Movies" asp-action="Index" method="get">
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
Title: <input asp-for="SearchString">
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movies[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Movies[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Movies[0].Price)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movies)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Blazor
@page "/"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
<div class="form-group">
<label>
User:
<input @bind="_userInput" />
</label>
</div>
<div class="form-group">
<label>
Message:
<input @bind="_messageInput" size="50" />
</label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>
<hr>
<ul id="messagesList">
@foreach (var message in _messages)
{
<li>@message</li>
}
</ul>
@code {
private HubConnection _hubConnection;
private List<string> _messages = new List<string>();
private string _userInput;
private string _messageInput;
protected override async Task OnInitializedAsync()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
.Build();
_hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
_messages.Add(encodedMsg);
StateHasChanged();
});
await _hubConnection.StartAsync();
}
Task Send() =>
_hubConnection.SendAsync("SendMessage", _userInput, _messageInput);
public bool IsConnected =>
_hubConnection.State == HubConnectionState.Connected;
}
Today, Blazor Server is not much different than an optimized MVC. In fact, Blazor Components are going to be usable in MVC web applications. Later, Blazor WebAssembly allows for the front-end to stand on it’s own completely running on the browser. If the connection is lost, the application is unusable until that connection can be restored. Although both use Razor, MVC uses the *.cshtml extension and Blazor uses *.razor extension.
Blazor WebAssembly and Blazor Server
Since Blazor WebAssembly is still in preview, Blazor Server is the only production-ready version of Blazor. Blazor Server is clearly an incremental step for developers/teams familiar with MVC to be able to shift their thought process over to an interactive browser app. This is because Blazor Server acts as an interactive browser app, but keeps a SignalR socket open to the server to create a diff of the DOM updates for each interaction. This means that the latency for Blazor Server is the sum of the network latency, server latency, and browser latency.
Blazor Server Benefits
- The download is smaller and startup is faster than the Blazor WebAssembly
- The app can fully leverage the server’s capabilities and full usage of the .NET Core APIs
- Debugging works on the server for the app
- Thin clients are supported
- The app’s .NET/C# code base, including the component code, isn’t served to clients
Blazor Server Downsides
- Higher latency due to network hops on interaction
- No offline support; if the connection fails, then the app stops
- Scalability can be an issue with multiple users due to handling of client connection and client state on the server
- An ASP.Net Core server is required to serve the app; no serverless deployments
Blazor WebAssembly Benefits
- No .NET server-side dependency, the app is fully functioning once downloaded to the client
- Fully utilizes the client resources and capabilities
- Work gets offloaded to the client
- Can be deployed without a web server such as a serverless deployment with CDN
Blazor WebAssembly Downsides
- App is limited by the browser
- Support is limited by the support of WebAssembly
- Initial downloads are larger and app load can take longer
- Runtime and tooling support are less mature
The Future for Blazor
Microsoft has a lot planned for Blazor. With the help of other tools and frameworks, Blazor should some day be able to run on nearly any platform you could think of. This means that a Blazor developer today could compete with JavaScript frameworks, but a Blazor developer tomorrow could be an iOS, Andriod, or Desktop developer as well.
Parting Thoughts
When Blazor and WebAssembly were introduced to me, I thought it was going to be something that completely changed the way we write applications. It may be, but, for now, I think the real purpose is providing more options for more developers to do great things with software. I have done Angular training but soon I may not need to bother. Blazor excites me with the potential it offers, but every technology, framework, and stack comes with costs and trade-offs. The reality is that this is just the beginning and it could be something great. Do you see yourself or your team using Blazor? Are you excited about WebAssembly? Maybe it is all just a waste of time? I’d love to hear your thoughts. Reach out to us via the social media links at the bottom of the page!
What’s Next
I’m going to be creating a tutorial for using Blazor WebAssembly. Once that is available, I’ll add a link here. I also have plans for specific parts of developing with Blazor WebAssembly, such as security and performance.