.NET 8 is bringing the biggest shake-up to Blazor since its debut. Remember the days when choosing a hosting model felt like being stuck between a rock and a hard place? Good news! Those days are almost over. With .NET 8, Blazor’s WebAssembly and Server models will come together in a harmonious union, accompanied by some other exciting surprises.
Welcome to the first in a series where we’re diving deep into the Blazor enhancements coming with .NET 8. Today, we’re exploring the sea change in how we’ll construct Blazor apps, the fading relevance of the hosting model dichotomy, and a sparkling new concept termed rendering modes.
A quick history of hosting models
There was a time, very early in Blazor’s experimental days, when hosting models weren’t a thing. Blazor was going to run on WebAssembly and execute entirely inside the client browser, and that was that. However, around July 2018 server-side Blazor was announced, briefly known as ASP.NET Core Razor Components, then ultimately renamed to Blazor Server.
This new way of running Blazor had the application hosted on the server with clients connecting over a SignalR connection. All interactions on the client flowed through this connection to be processed on the server with UI updates sent back to the client where they were applied to the DOM.
And so, hosting models were born.
Currently, we have 4 hosting models for Blazor:
- WebAssembly (web apps)
- Server (web apps)
- Hybrid (desktop & mobile apps)
- Mobile Blazor Bindings (experimental)
The great thing? Components from the top three models are usually interchangeable. A component running in a Blazor WebAssembly app, can be lifted and run in a Blazor Hybrid application and vice versa (generally speaking). However, Mobile Blazor Bindings uses a different approach with components inspired from Xamarin Forms. This slight change of approach makes components written for the other hosting models incompatible with MBB.
The Hosting Model Dilemma
The problem that has been a thorn in the side of Blazor developers since almost the beginning: Which hosting model to pick. I’m specifically talking about building web applications now. Should it be WebAssembly or Server? What if I want to change further down the line? How much work would that be?
Of course, as developers, we’re notorious for staking our claim and championing our chosen approach. Remember the age-old tabs vs. spaces feud? Yeah, same energy when it comes to hosting models!
The reality is that neither hosting model is perfect. Each of them have their pros and cons. Let’s take a look.
The server hosting model has some very compelling advantages:
- Code Security - All code stays on the server and away from prying eyes, it’s never downloaded to the client.
- Full .NET Runtime - As a developer get access to the full .NET runtime. The application is running on the server and therefor you’re not subject to any restrains.
- Development Speed - You don’t need a separate API project as you can connect to resources such as databases or file systems directly.
However, it’s not all roses. There are trade-offs to picking this hosting model:
- Constant Network - It requires a stable connection between client and server. Even a small blip in the connection will result in the dreaded attempting reconnect overlay which makes the application impossible to use.
- Network Latency - As all interactions are being processed on the server, they have to be sent from the client and a response awaited. If the client and the server are too far apart, this can result in perceivable lag for the user.
- Cloud Costs - As this is a server based hosting model, all clients are connecting to the server. This means the more connections the application has, the higher the specs of the server and more it will cost.
As you can see, there are some great pros, but the cons are not insignificant. Now let’s take a look at Blazor WebAssembly.
Here are some of the advantages WebAssembly offers:
- Free Hosting* - It can be hosted for free as there is no need for a server based .NET runtime. Blazor WebAssembly apps can be run from places such as GitHub Pages, Netlify, Azure blob storage or Amazon S3 buckets.
- Scalable - Following on from low hosting costs, is low scaling costs. Due to the app running entirely on the client, there can be little to no additional cost for onboarding more users.
- Network Resilience - As it runs completely on the client, it also works well with unstable networks. By adding a service worker, Blazor WebAssembly apps can run as PWAs with very little effort. There is even a setting for this when creating a project.
But what’s the cost?
- Download Size - It’s great that apps can run entirely on the client, but that does means that all the files need to be downloaded to the client in order to execute the application. This means the entire .NET runtime along with framework and application assemblies. Even on fast connections this results in a pause before the application comes to life.
- Restricted Runtime - As the app is running in the browser, there are certain restrictions on how the runtime can execute. This means that instead of using JIT, which is the most common way .NET applications execute, Blazor WebAssembly uses an interpreter which is much slower, especially for CPU bound tasks.
- Code Security - This isn’t so much an issue with the hosting model as an extra consideration for the developer. But as the entire application gets downloaded to the browser, dlls can be decompiled. Meaning that any sensitive logic needs to be put behind an API.
As you can see, both hosting models have some fantastic advantages, but neither is without it’s compromises.
Wouldn’t it be marvellous if we could cherry-pick the best of both worlds? Imagine harnessing Blazor Server’s lightning speed and combining it with Blazor WebAssembly’s resilience. And here’s the twist: .NET 8 seems to be promising exactly that!
Full Stack Web UI with Blazor
.NET 8 is ushering in a new era where you won’t be boxed into a single hosting model. Think flexibility, modularity, and personalization. You can tailor how each page or even individual component renders. It’s like having your cake and eating it too!
Instead of committing to a single hosting model for your entire application, you can now mix and match based on the needs of specific pages or even individual components. For instance, a static contact page might use server-side rendering for performance, while a real-time dashboard might use the WebAssembly mode to leverage client-side capabilities. It’s all about giving developers the tools to make the best architectural decisions for each scenario.
How is all this going to be achieved I hear you ask, the answer is a new concept called render modes. Let’s explore each of them and see what they can do.
Channelling the power of traditional web apps, this mode is reminiscent of how Razor Pages or MVC applications function. Server-side Rendering, or SSR, is when HTML is generated by the server in response to a request.
When using this mode, applications will load extremely fast as there is no work required on the client, and no large WebAssembly assets to download. The server is just sending HTML that the browser then renders. This also means that each request for a new page results in a full page load, as summarised in the illustration below.
At this point you might be asking what’s that point of this when Razor Pages and MVC already exist? That’s a good question, and the main reason is that neither of those frameworks offer a good story around building reusable components. Blazor has an excellent component model and this mode allows that to be leveraged for more traditional server-rendered sites.
I think another interesting angle to consider is that Microsoft are positioning Blazor as their preferred UI framework going forward. Over the last few versions of .NET, there’s been a lot of focus on making .NET more approachable to new generations of developers. Along this line, one criticism .NET has had is that there are so many options for doing things that it puts people off. This feel like an attempt to fix that. Learn Blazor and you’ll be able to build any type of UI, web (both static and dynamic sites), mobile, and desktop. It’s just a theory, but I think it has some legs.
Think of this mode as the middle ground between server and client rendering. Let’s pretend we had a page in an applications that needed to make an async call to fetch some real-time data–either from a database or another API. If we used the SSR mode we just covered, that would mean having to wait for that async call to complete before returning any HTML to the client. This could result in a delay loading the page. Also, there isn’t any other interactivity in our page so using Server or WebAssembly mode would be a massive overkill. This is where streaming rendering comes in.
When using streaming rendering, the initial HTML for the page is generated server-side with placeholders for any content that is being fetched asynchronously. This initial response is then sent down to the browser to be rendered. However, the connection is kept open and when the async call completes, the remaining HTML is generated and sent down to the browser over the existing open connection. On the client, Blazor replaces the placeholder content with new HTML.
It’s all about enhancing the user experience by minimizing wait times.
While this retains the essence of the classic Blazor Server model, its granular application is the standout feature.
When selecting this mode a page, or component, will be optionally pre-rendered on the server and then made interactive on the client via a SignalR connection. Once interactive, all events on the client will be transmitted back to the server over the SignalR connection to be processed on the server. Any updates required to the DOM will then be packaged up and sent to the client over the same SignalR connection where a small Blazor runtime will patch the updates into the DOM.
If you’ve been working with Blazor for a while, none of this is new, except that you’ll now be able to decide this on a page by page or component by component basis!
The OG traditional SPA approach. This model is derived from the Blazor WebAssembly hosting model and fully capitalises on client-side capabilities, allowing C# code to run in the user’s browser.
Using the same example as Server mode, the stock prices page would be downloaded to the client along with the various framework DLLs and WebAssembly runtime. Once on the client, it would be bootstrapped and the page loaded. Any API calls to get data would be made and the UI would be re-rendered as necessary to display any data returned.
One thing to note about any components marked as
RenderMode.WebAssembly is that they need to be referenced in a separate Blazor WebAssembly project to the main Blazor Web project. This is so that the framework can determine what code and dependencies need to be sent down to the client. If you want a component to run on both the server and the client, then the component should be placed in a Razor Class Library project that is references from the main Blazor Web project and the Blazor WebAssembly project.
If there were an MVP among the rendering modes, this might just be it.
Since the early days of Blazor, developers have been asking for a way to combine the benefits of Blazor Server and Blazor WebAssembly. And with .NET 8 that request will become a reality. When setting a page or component to use Auto mode, the initial load of that component will be via server mode making it super fast. But in the background Blazor will download the necessary assets to the client so that on the next load it can be done using WebAssembly mode.
While this rendering mode will address the biggest pain point for developers when embarking on a new Blazor project, what hosting model should we use? There are no free lunches.
Auto mode will increases the complexity of applications. Every component marked with
RenderMode.Auto will need to execute on both the server and the client. Meaning that there will need to be some form of abstraction in place if the component needs to fetch any data.
Other things that spring to mind are pre-rendering and security. However, at the time of writing, Auto mode isn’t available as part of the .NET 8 previews so I’ve not been able to delve into these topics just yet, but as soon as I can, I will.
In this post, we’ve taken a first look at the major change coming to Blazor in .NET 8: Full stack web UI. Full stack web UI represents the biggest shift in the Blazor eco-system since the introduction of hosting models and is set to position Blazor as the “go to UI framework” for modern web applications built with .NET.
The new render modes give developers a huge amount of flexibility with their applications. We’ll be able to control how our applications are rendered at a per-component level. And Auto mode addresses one of the major pain points for developers getting started with new Blazor projects. But it’s not all sunshine and rainbows.
With great power comes great responsibility. Potentially having multiple render modes per page will create additional cognitive load for developers. If using Auto mode, developers will have to write server based code for fetching data, as well as traditional APIs as components will be run on both the client and server.
Personally, I’m extremely excited for what’s coming, but I’d love to know what your thoughts are? Leave a comment and let me know.