What Blazor’s Move to .NET 5 Means for You

.NET 5 is released, and with it, Blazor reaches a new milestone. It officially graduates from a small experiment to a production-ready framework built into .NET 5 that ships with ASP.NET Core out of the box.

The updates enable advanced features for your web apps and massive performance improvements. Developers can use Blazor in combination with GrapeCity’s ComponentOne Blazor UI Controls to create browser-based single-page applications (SPA) almost entirely in C# with only a few lines of JavaScript.

.NET 5’s overarching goal is to lay the foundation for a unified platform, with a common set of APIs extending across all experiences. Platform unification is why Microsoft dropped “Core” from the name: there is no longer a need to differentiate it as unique.

Instead, developers can work from a single SDK and simply specify a target framework name (TFM) for their apps. Most apps only need to target net5.0, but libraries in an app requiring Windows-specific APIs to access native functionality can target net5.0-windows. The same goes for Linux and other platform targets.

What about .NET Standard? In The Future of .NET Standard, Microsoft .NET Program Manager Immo Landwerth explains that the TFM version number is what’s important moving forward. .NET 5 and future versions will continue to support .NET Standard 2.1 and earlier.

Apps should target the lowest common denominator for maximum reach. For example, for your app to run on .NET Framework, target .NET Standard 2.0. You can also multi-target multiple platforms to take advantage of platform-specific features like phone text messaging.

Let’s look at some Blazor performance improvements and new features in .NET 5, and how they help your development efforts.

Becoming One .NET

Blazor not only ships as part of .NET 5 but is built from the same codebase. As the announcement for .NET 5 explains, the Blazor WebAssembly runtime and libraries are built from the same consolidated repository. For example, Blazor shares the same dictionary lookup code as the other runtimes.

Therefore, Blazor takes advantage of .NET 5 performance enhancements and optimizations. In fact, between .NET 5 improvements and enhancements to the Blazor framework, Blazor WebAssembly now runs two to four times faster than the prior version.

The graph below shows a visual summary of improvements in .NET 5 compared to .NET Core 3.1. There have been significant improvements to operations common to web applications such as text manipulation, use of regular expressions, and Language Integrated Query (LINQ). Blazor automatically inherits these benefits.

blazor performance

You can read more in Performance Improvements in .NET 5.

Sharing the .NET 5 codebase doesn’t mean Blazor is capable of implementing all the core APIs. For example, opening user datagram protocol (UDP) sockets in the browser sandbox, with or without WebAssembly, isn’t supported. The Blazor framework uses metadata to mark APIs that are not supported in the browser.

When you add new libraries or migrate existing code to Blazor, you can use the .NET platform compatibility analyzer to identify APIs that may no longer work.

A major benefit of the shared codebase is a unified runtime between the client and server. The classes, interfaces, and business logic you define are reusable simply by referencing the project or dynamic-link library (DLL). This provides consistency and continuity because the entities exposed by your Web API controllers are the same entities consumed by the HTTP client in your browser.

You can use the same validations to provide immediate user feedback in client forms and ensure the service’s data integrity before committing changes to your database backend.

Blazor Performance Optimizations

Blazor’s performance improvements don’t stop at the .NET 5 enhancements. The Blazor team invested heavily in framework-specific performance improvements. For example, Blazor now supports lazy load assemblies.

For large enterprise applications, this can significantly improve application startup time. Instead of loading everything upfront, developers can, for example, defer loading the sales project until the user navigates to an area that requires it.

Blazor’s front-end framework uses the Razor engine to render the browser-based user interface (UI). Because every page must be rendered, improvements to this engine can have a major impact on your application’s overall responsiveness. The ASP.NET team runs benchmarks as part of the continuous integration and continuous deployment (CI/CD) process.

You can view the code for the benchmarks and the results in this GitHub repository. The figure below shows how fast Blazor renders 10 items. There is a significant improvement from .NET Core 3.1 to .NET 5.

render time

Blazor WebAssembly apps are client applications relying on API calls to retrieve and mutate data. The most common protocols use JavaScript object notation (JSON) as the payload for requests and replies.

As a result, many Blazor apps spend significant cycles serializing C# classes to JSON then deserializing the results. The release of .NET 5 has substantially improved the performance of translating between C# and JSON, as you can see in the figure below.

blazor dotnet

You can visualize just how significant the improvements are in the graph below, with the relative time to render and deserialize between .NET Core 3.1 and .NET 5.

blazor performance

If you prefer to skip the numbers and benchmarks and see Blazor on .NET 5 in action, head over to GrapeCity’s ComponentOne FlexGrid demo.

You can interact with a live demo in your browser, checking out features like sorting, filtering, and editing. Unlike other component libraries that simply wrap existing JavaScript-based controls, the ComponentOne Blazor UI controls are native Blazor controls.

Improved Inner Loop

The “inner loop” refers to the development phase of the application development lifecycle. Developers want a fast inner loop. The longer it takes to build, deploy, and test your code, the harder it is to quickly deliver features and respond to defects. Blazor improves the inner loop experience by addressing activities like updating and debugging code.

You can debug Blazor WebAssembly apps directly in your browser. The Blazor debug experience has several improvements in .NET 5. The debug launch is simpler, faster, and more reliable. Earlier versions of Blazor had only limited support for inspecting local variables.

This is now updated to handle more complex types. The debugger is now able to step through asynchronous code that is quite common in Blazor apps due to the need for asynchronous communication over web APIs.

Web developers expect to see live website changes as they edit code. Blazor supports “hot reload” through the dotnet watch run command. The command automatically launches your default browser, renders your Blazor app, and watches for changes. Saving edits automatically refreshes the browser with your changes in place. The refresh happens faster with the latest Blazor version, saving you time as you edit and update your code.

New Blazor Features for .NET 5

The Blazor team didn’t just focus on performance and productivity. They introduced a variety of new features that make line-of-business web apps shine. Here are just a few of these game-changers:

CSS Isolation

Blazor is a component-based framework, so it makes sense to define CSS at the component level. CSS isolation does just that: it enables you to define styles that are scoped to a specific Razor component. Multiple developers no longer have to merge updates to a single, global stylesheet.

It’s also easier to avoid conflicts with styles and style names. Using this feature is as simple as adding a file with the name of your Razor component followed by the CSS suffix. For example, if you have a component named ComponentOne.razor that looks like this:

@page "/ComponentOne"  
<h1>Scoped CSS</h1>

You can add a file named ComponentOne.razor.css that looks like this:

h1 {  
  color: blue;  

The result is a blue heading that doesn’t impact the rest of your app. For full details about CSS isolation, read the official docs.

Easier File Uploads

If you work with web apps, chances are you’ve either written a long block of code or grabbed a third-party control to manage file uploads. Handling uploads has always been tricky, until now. Blazor on .NET 5 introduces the InputFile tag. Adding an upload control to your web page is as simple as:

<InputFile OnChange="@OnInputFileChange" multiple />

The changes event fires with metadata about the files selected. You can then request a stream to download the file. If the files are images, helper methods optionally resize the image in the browser before streaming the image to the server. For more details, read the documentation for Blazor file uploads.

Component Virtualization

Performance suffers in web apps forced to render extremely large lists with thousands of items, due to the resource cost of rendering individual items. Users don’t look at thousands of items at once, but typically scroll through to view a small set of items at a time.

Virtualization takes advantage of this behavior by waiting to render components until they come into view, reducing delays. This improves the overall user experience by providing a faster, more responsive app with perceived performance improvement.

Blazor now supports component virtualization for lists that render items at a fixed height (this enables computing the correct offsets to begin rendering as items move into view). Using this new feature is simple. If your existing code looks like this:

    @foreach (var contact in contactList)  
        <ContactDetail @key="contact.Id" ContactInfo="@contact" />  

You simply move it into the virtualized component like this:

    <Virtualize Items="@contactList" Context="contact">  
        <Contact @key="contact.Id" ContactInfo="@contact" />  

The containing divider should be styled for a fixed height with an overflow-y set to scroll.

The component also supports asynchronously streaming new items to handle lists larger than what is practical to load into memory. Details are available in the virtualized component documentation.

Azure Active Directory Integration

Authentication and authorization are fundamental to most enterprise applications. Security is challenging in browsers because the client is in full control of the environment and therefore is able to bypass code and checks.

Although no browser app can be fully locked down, Blazor makes it easier to apply security mechanisms with Microsoft Identity v2 and MSAL v2.0.

Microsoft Identity’s platform manages user identity through Microsoft accounts (including Azure Active Directory) and social media logins. MSAL is a library for implementing authentication and authorization in the browser. Both work together to simplify securing your web-based Blazor apps.

Learn more by reading this Blazor security overview.

Improved Trimming and Linking

Blazor WebAssembly code is optimized when you build or publish in release mode. Libraries are linked and then scanned for unused code. Blazor trims the code, resulting in a much smaller package size for download.

Although this works in most situations, some libraries use indirect APIs, such as reflection, to execute code. The trimming algorithms may not detect this code, then remove needed code, resulting in a runtime exception.

Fortunately, the latest Blazor offers new options to control this process. To learn how, read Configure the Trimmer.

These highlights just touch on a few of the major enhancements now available to you. For the full list of changes, read the ASP.NET Core 5 Blazor release notes.

What Will You Build Next?

Now that Blazor WebAssembly is production-ready and ships with ASP.NET Core, you can create a high-performance browser-based line of business applications using C# that connect with your existing .NET projects.

Take advantage of new features like virtualization and combine them with ComponentOne controls to build incredible web apps.

What will you build next? Learn more about GrapeCity’s Blazor UI Controls for Web Apps and get started today!

Jeremy Likness

comments powered by Disqus