Meet the Blazor
22.04.2022
When you're thinking about a framework for your future app, there are many options to choose from. In today's piece, we want to talk about one of them and give a couple of pointers as to why Blazor should be your choice in 2022.

When you’re thinking about a framework for your future app, there are many options to choose from. In today’s piece, we want to talk about one of them and give a couple of pointers as to why Blazor should be your choice in 2022.
Blazor is a free and open-source web framework that came out in 2018 with the help of Microsoft. It allows developers to build web apps using only C# and HTML, developing both client and server sides using a single framework.
Blazor currently has two application types which differ by their execution strategy – Blazor WebAssembly and Blazor Server apps. More specifically, these types are named after their hosting models.
Blazor WebAssembly Apps
It is a single-page app that executes entirely in the user’s browser. In other words, when a user navigates by the URL of our app, they receive webassembly-based runtime in response. Then it will be used for executing the application. Together with this runtime, the user also receives an app assembly and all it’s dependent assemblies needed for running the application.
On the screenshot below, you can see the simple structure of an application of this type.
WebAssembly apps usually include directories where you can store the shared components or routable components, a folder called “wwwroot,” where you can keep the static assets, and the index.html file. The last one has two primary functions. Firstly, it contains an HTML element that helps the app identify where we should place our root component and render the application. In addition to this placeholder, index.html refers to a JavaScript file called blazor.webassembly.js. It is responsible for downloading our runtime, all of its dependencies, and bootstrapping the app.
Blazor WebAssembly apps have their unique advantages:
- Since our app is working in the user’s browser, the server is less loaded. We don’t have any network latencies because we don’t make requests to the server.
- Blazor WebAssembly app can be hosted by static file servers, not only by ASP.NET Core app hosted by the web server. For example, you can use Github Pages to host your app.
- This type of apps continues functioning even with lost connection since they run directly in the browser.
However, Blazor WebAssembly apps have some limitations as well. The main one is that you need a browser that supports WebAssembly, but hopefully, all the latest versions of most browsers support this technology.
Another limitation is the loading time of your page. App execution needs to load a runtime and a set of additional libraries on the first request. It has some negative impacts on app loading time.
Also, Blazor WebAssembly apps use a more limited version of .NET runtime which doesn’t have all the functionality compared to the standard runtime.
Blazor Server Apps
The second type of apps that can be developed using ASP.NET Core Blazor called Blazor Server. In the case of this app type it is executed on the server. You have a client and a server which communicate with each other using SignalR connection.
The base structure of a simple Blazor Server app looks like this.
It is pretty similar to the Blazor WebAssembly app. The only difference is that you don’t have an index.html page. But we have _Host.cshtml which is a root page of our app. Whenever a user navigates by URL of our app, they receive a rendered version of the _Host.cshtml page which also specifies where the root component of our app should be placed. _Host.cshtml itself refers to the JavaScript file blazor.server.js which is responsible for establishing a SignalR connection.
Since our app is executing on the server, we don’t need to load anything to the user’s browser like runtimes or additional assemblies. As a result, the app loads faster compared to Blazor WebAssembly. Also, Blazor Server can be used by browsers without WebAssembly support. Another advantage of server side execution is the possibility to use all capabilities of .NET runtime.
If we’re talking about limitations, such apps can be served only by the ASP.NET Core app. And if the server goes down and the connection fails, the client can’t function properly.
Blazor Framework Concept
This framework has several exciting features. The main is components. We follow a component-based approach when we develop Blazor apps (not depending on execution strategy). Every app represents a hierarchy of components that can be reused. It decreases development time and helps to avoid code duplication.
You can create two types of components – routable and non-routable.
This is how a simple routable component looks. You can identify it by the @page directive, and every time users navigate by a specific route, the component will be rendered to the user.
The Component concept has a list of its benefits.
Routing. Routing is enabled by including the <Router> component in the root component of your app. The following algorithm can describe the process. <Router> component receives a parameter called AppAssembly. When we specify the parameter, we command Blazor to use the assembly as the source of all the routable components we are going to use in our app. All routable components allocated in the assembly will be fetched and added to the route table during the app bootstrapping process. Once our app is bootstrapped, this root table will be used as a source of routes corresponding components. It’s also possible to specify additional libraries containing our routable components.
Dependency Injections. Blazor supports dependency injection into components either by adding @inject directive in components markup or marking corresponding property with [Inject] attribute. You can inject dependency when, for instance, your components have dependencies from external services, and they may need to fetch data from some Rest API
The approach you choose for dependency injection mostly depends on the structure of your component. If you have a single file component, you will inject the dependency directly in the component file with the markup by adding @inject directive and specifying a type of your dependency together with it’s name.
In case when we’re talking about more complex components, which consist of two files: file with component markup and file with C# code, better approach will be to inject your dependency in the C# class by marking corresponding property with attribute [Inject].
Lifecycle events. It is also possible to execute additional logic during the component initialization and rendering process. This feature is similar to Angular lifecycle hooks, if you have experience with this framework. In the case of Blazor, all lifecycle events are virtual methods, so they can be overridden.
CSS Isolation. This feature was added in .NET 5 release. Using CSS isolation, you can isolate CSS styles of your components, so they will be applied only to your component, but not globally. It helps to prevent conflicts between styles from different components.
The CSS isolation happens at build time. The Blazor engine rewrites the CSS selectors by including unique attributes in each of them. The same attributes are added to the rendered HTML markup. The rewritten CSS styles are bundled and included into a single static asset.
JavaScript interoperability. Developers who develop Blazor applications are able to call JavaScript methods from C# code as well as call C# methods from JavaScript code. For example, it can be useful to call JavaScript method from C# code when we need to store some data in the browser’s local storage.
Unit testing. Currently there are no oficial libraries provided by Microsoft for writing unit tests for components. However, Microsoft itself recommends to use a library called bUnit for writing tests for our components. This library allows us to write a wide range of unit tests including testing of the component behaviour, verifying of the component markup, created after it’s rendering etc. Also, you can use some external libraries, for example Moq.
Debugging. Debugging of Blazor Server apps is the same as for the regular ASP.NET Core apps. In case with Blazor WebAssembly, it’s possible to debug such apps in Visual Studio without any additional configurations. You can just run your app in debug mode. Also you can use Visual Studio Code (but you need to install additional extensions). It’s also possible to debug Blazor WebAssembly apps in Chromium-based browsers.
Tips for WebAssembly apps
At the beginning of the article, we mentioned that along with all the convenience of Blazor WebAssembly apps, their loading speed is slower than that of Blazor Server apps. Therefore, in the end, we will give a few proven tips and techniques that you can use to increase app performance and decrease the time of page loading.
- Use Intermediate Language trimming when publishing an app. When we publish our app, its assemblies may have some unused code and as a result – bigger size. You can remove unused code from the result assembly by using IL trimming. Note: IL trimming performs static code analysis, so you may have some surprises if your app heavily relies on reflection. Don’t forget to re-test your app before publishing.
- Use compression when publishing an app (Brotli and Gzip compression algorithms can help). Compression is enabled by default in Blazor, and results show that you can compress files up to three times compared to the original ones.
- Use Lazy Loading. This is a fresh feature that enables you to improve the load time of your Blazor WebAssembly app by deferring the download of specific app dependencies until they are required.
- Optimize components. You can use paging for displaying grids with lots of records. Another option is to use component virtualization when you render only those parts of the component visible to the user at a given moment.
- Disable unused features.
We hope the material was helpful for you, and you will think about Blazor as the base for your web application.
Katryna Zorina
Software Engineer at devspiration