Exploring Blazor Changes in .NET 8 - Auto Render Mode

September 6, 2023 · 4 minute read · Tags: blazor

This is the latest in a number of posts where we’ll explore the changes coming for Blazor in .NET 8 (due later this year - 2023).

They say there’s no such thing as a free lunch, and that’s certainly true when it comes to Blazor’s existing hosting options.

Choose Blazor Server and you get a fast initial load, but then a degree of latency as every DOM interaction is sent to the server (via SignalR). You also need to scale your server to handle the required number of concurrent connections.

Opt for Blazor WASM and you get a slow initial load, while the framework and your app is downloaded by the user’s browser, but then everything runs fairly snappily as DOM interactions are handled within the browser.

But what if you want the best of both worlds - Fast initial load plus low latency DOM interactions?

For that we have .NET 8 and its new auto render mode.

Have your cake and eat it too

.NET 8 defaults to Server Side Rendering for your components with the option to make individual components run ‘interactively’ (using Blazor WASM or Blazor Server).

Now, with .NET 8 preview 7 (and higher) you can opt for “auto” render mode instead.

This uses WebAssembly to render your component, but only if the .NET WebAssembly runtime can be loaded.

Typically this means, if the user’s browser has previously downloaded (and/or cached) the runtime, or they’re running on a super-fast network connection, they’ll get Blazor WASM.

If the runtime can’t be loaded quickly enough then the framework will fall back to using Blazor Server while the .NET WebAssembly runtime is downloaded in the background.

Crucially, for your users, this means components which are interactive as soon as the page loads, but which aren’t dependent on that Blazor Server connection after the first time (meaning less load for your server, and lower latency for ongoing DOM interactions).

Here’s a simple example of it in action.

First, a Banner component:

<div class="card">
    <div class="card-body">
        @Text
    </div>
    <div class="card-footer">
        <button class="btn btn-primary" @onclick="SayHello">Click me</button>
    </div>
</div>

<p>@message</p>
@code {

    [Parameter]
    public string Text { get; set; }

    string message;

    private void SayHello()
    {
        Console.WriteLine("Hi from banner");
        message = "Hi!";
    }

}

Which is rendered via the Index page.

@page "/"

<PageTitle>Home</PageTitle>

<h1>Home</h1>

<Banner @rendermode="@RenderMode.Auto" Text="Hello"/>

Notice the rendermode is set to Auto.

When we run this in the browser we see the socket connection, then Blazor WASM finishes loading shortly after:

Auto Render Mode

For this visit the Banner component has been rendered via Blazor Server and will continue running on Blazor Server until the user moves away from the page (or closes the browser).

Next time we run the app, because the app and framework are already cached in the user’s browser Blazor WASM will be able to load and the component will run via WASM instead.

Making It Work

Something to bear in mind here - making components interactive using WebAssembly requires some very specific configuration and architecture for your app.

Any components which need to run via WASM need to be located in a separate project (because you probably don’t want your server projects being downloaded to the browser!)

Auto Render Mode Folder Structure

Changes to the Server project

The Server project needs to reference the Client project.

You’ll need to update the _Imports.razor file to include the namespace for the components from the client project:

...
    
@using LinkedInDemo.Client.Pages

You’ll also need to reference the following NuGet package in your Server project:

dotnet add package Microsoft.AspNetCore.Components.WebAssembly.Server

Finally, to actually enable rendering on both server and WebAssembly you’ll need to update the calls to AddRazorComponents and to MapRazorComponents in the server project’s Program.cs:

...

builder.Services.AddRazorComponents()
    .AddServerComponents()
    .AddWebAssemblyComponents();

...

app.MapRazorComponents<App>()
    .AddServerRenderMode()
    .AddWebAssemblyRenderMode();

With that in place, you can now add components to the Client project, then reference them from components in your Server project and enable auto render mode whenever it makes sense to do so!

Join the Practical ASP.NET Newsletter

Get every .NET 8 article first, delivered straight to your inbox.

I respect your email privacy. Unsubscribe with one click.

    Next up

    Interactive what now? Deciphering Blazor’s web app project template options
    Create a new Blazor Web App and you’ll be asked how you want interactivity to work, but what does it all mean?
    Should I put my Blazor components in the server project, or the client project?
    .NET 8 gives you a choice of projects, which one should you use?
    Share user authentication state with interactive WASM components
    Your server knows your user is authenticated, but what about your interactive WASM components?