Sunday 9 May 2021

Blazor framework: What I learned

1. Introduction

Hi, there just want to share my experiment with the Blazor framework. I have developed front-end using ASP.NET MVC and React.js before in a commercial capacity. Blazor has been there for a while before I decided to give it a try on my projects at work.

Initially, I tried the Blazor server in one of my projects, the MESH API client. As part of the project, I needed to build a front-end to manage the mailboxes for the MESH API client, to view unprocessed messages. I had three full weeks and so to implement from start to finish. The functionalities in my project are not that much, however, to be able to learn and be productive in a week, by far the quickest UI framework I have learned, by par with ASP.NET MVC. The story was slightly different from when I learned React.js, which took more time to become productive and understood different moving parts of the framework, such as webpack, router, and state management.

Blazor has many similarities with React.js, both support composable UI, local routing, and state management. Though, the way blazer implemented those, much simpler for C# developers. For example, if you change local variables in a component it will update the UI by default, not so with React.js. The lifecycle of the component is also much simpler (only a couple of steps you need to remember). The routing component is build-in in the Blazor framework, where React.js you will need to install a different package. I also found working with the async method much simpler in Blazor (or C#) rather than React.js (javascript) with await async keyword, but this may be only the case for C# developer.

2. Blazor Server and Web Assembly

Blazor comes in two flavors, server, and web assembly. The main difference is Blazor server hosts the UI component in the server and communicates with the client (browser) using SignalR via binary messaging. Microsoft did a good job in optimizing the communication, and the payload generally very small and fast. For example, updating data in a component will trigger communication between browser and server. For a programmer, when working with Blazor server, you need to understand that you are on a server-side, so you will be able to call server API or server service locally, but generally, it is recommended to call server API through inter process communication, or externally. The reason is to be able to port your application with ease to web assembly later on. 

Both versions, server and web assembly, share the same UI model, only the hosting is different. Blazor also allows interoperability with javascript, but when the component is prerendered in the server (e.g Blazor server or prerendered Blazor web assembly), the javascript call needs to be delayed until they are in the browser context. See this for more information here When I implemented the Blazor server, the thing that caught me off guard is that when you implemented a local timer, the timer is hosted in the server, not in the browser. To use the browser timer, you will need to call javascript via javascript interop. However, when you work in a Blazor web assembly, a local timer is a browser timer by default.

Blazor web assembly on the other and is hosted in the client (browser), so you need to think when you are coding that you are on the client-side. Blazor web assembly also comes with a host builder in the main program like the .NET core application below

	
public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");
            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
            builder.Services.AddOptions();            
            builder.Services.AddScoped<ViewModel>();            
            await builder.Build().RunAsync();
        }
    }

The builder has an Inversion of Control service, where you can registered services used in the application component. The difference with the Blazor server is all services must have a lifecycle of Scoped or Singleton, though Scoped will be interpreted as a Singleton, and no transient. You can have a read on lifecycle services in Blazor in this article  

The other technique I found useful is registering a global state (View Model), which represents all data within the application. By registering the global state or view model in the builder, you can inject the global state anywhere in your application.

Another important thing is to propagate the change to other components in the application. For example, if you add new data row in one component, and you have other components in the application that shows the number of row of the same data. There are a number of ways as demonstrated in this article here 

Basically, there are three ways: EventCallbacks, Cascading Values, State Container. EventCallbacks mechanism is the current component that calls its event, and any other components that have registered to the event will be notified of the changes. Cascading values mechanism is where the parent component passes the changes automatically to child components. The State container mechanism is a global state mechanism, so when a particular data changes it will call the global state event, and any components that registered to that event will get notified. In my application. 

I use a state container to propagate change between components, however, if you have more time, you can devise a better mechanism using Cascading Values of EventCallbacks mechanism which will allow you to design a component that is not dependant on the global state and can be reused in other applications, particularly if you design a component library.

Though I would recommend Blazor for any C# developer, for ease of use and productivity. There are caveats in terms of performance and scalability compared to another framework like React.js. For Blazor server, since all UI components are hosted on the server, every browser session will need a corresponding host in the server, this apparently will limit its scalability. While Blazor web assembly, the main drawback is the loading time when starting the application, and there may be others as shown in the article. Blazor is still very early on their development, and more optimization will come, but for now, they are not the top choice for high traffic websites, landing pages or web applications. They can be used for low-traffic web applications such as intranet apps, support web pages, etc. 

3. Application Examples

NB: All data are tests data only

3.1 Blazor server

Initially, I tried the Blazor server on my MESH API client project, which is intended used by support staff. It takes me roughly two full weeks to complete the UI and learn the framework along the way. However, you can be productive within a day or two already. The learning curve much much faster, and much simpler than learning React.js. All the toolbox chain is already built-in within the .net core or framework and accessible via .NET core CLI or Visual studio, so you are set to go from the start. 

When building for the application I also learn how to integrate with the server via API call. Blazor using System.Text.Json, which is unfortunately not fully compatible with another serialization library such as Newtonsoft. Here is the article that listed the supported features.  Here are few examples of the screenshot when developing the MESH API client project front-end.

3.2 Blazor Web Assembly

Having completed the MESH API client project in the Blazor server, I am ready to try on Blazor web assembly. I had two projects on the queue to be implemented as Blazor web assembly. The first one was the front-end for integration to Summary Care Report API, which I need to develop to demonstrate and test the end-to-end integration with the API. Having experience with Blazor server before, created Blazor web assembly application was quicker, I completed the application within one week with integration to the server. 

The second project was front-end for integration with Pathology and Screening adapter. and this is the screenshot. The time to finish this was much quicker which was only took three days, and I have the opportunity tried with Web Compiler and SASS for the CSS.


Verdict: Using Blazor I have been able to create an application quicker and cleaner, compared to my experience with ASP.Net MVC or React.js. There is not much problem with the application I have created. The only caveat is on serialization between client and server, which limits the kind of object I can pass without resorting to passing a string, and Blazor generally may not be ready yet for the high-traffic web application, but it is a fabulous choice for low to medium traffic and intranet application. 

No comments:

Post a Comment