Search code examples
blazorblazor-server-side

Running Blazor ver 8 in InteractiveServer (streaming) mode


I am trying to convert my Blazor server-side (ver 6/7) app to version 8. I want to continue in server mode so InteractiveServer, not InteractiveAuto.

The way to display my pages the fastest is to set StreamRendering(true) - correct?

And this will then call OnInitializedAsync() twice where I do anything fast on the first call and hit the database on the second call - correct?

[CascadingParameter]
private HttpContext? HttpContext { get; set; }

[Inject]
private ILogger<Counter>? Logger { get; set; }

private int currentCount = 0;

/// <inheritdoc />
protected override Task OnInitializedAsync()
{
    bool firstRender = !(HttpContext is null);
    Logger.LogInformation($"firstRender = {firstRender}");
    return base.OnInitializedAsync();
}

The only way I can get this to work is to put the following at the top of the razor file (Counter.razor) in this case:

@attribute [StreamRendering(true)]
@rendermode InteractiveServer

I tried the following in App.razor and it made no difference. Still needed the @rendermode. Why?

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="Blazor_Ver8.styles.css" />
    <link rel="icon" type="image/png" href="favicon.png" />
    <HeadOutlet @rendermode="InteractiveServer" />
</head>

<body>
    <Routes @rendermode="InteractiveServer" />
    <script src="_framework/blazor.web.js"></script>
</body>

I have the following in Program.cs. Does this set @rendermode="InteractiveServer" if @rendermode is not explictly set?

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

And the final question - am I wrong to try and set @attribute [StreamRendering(true)] and @rendermode InteractiveServer globally and should be setting it for each component? And this is a component, not a page setting - correct?

I'd prefer that I set it globally and everything, unless explicitly set otherwise, uses that setting. If that won't work, I'd like to set it for every page and every component in the page then uses it (assuming it is not expressly configured different).


Solution

  • The way to display my pages the fastest is to set StreamRendering(true) - correct?

    If you're running in InteractiveServer global, forget about StreamRendering.

    And this will then call OnInitializedAsync() twice where I do anything fast on the first call and hit the database on the second call - correct?

    Yes.

        <HeadOutlet @rendermode="InteractiveServer" />
    </head>
    
    <body>
        <Routes @rendermode="InteractiveServer" />
        <script src="_framework/blazor.web.js"></script>
    </body>
    

    Will make everything InteractiveServer.

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents();
    

    Just adds all the services required to run InteractiveServer. It doesn't set the application mode.

    And the final question - am I wrong to try and set @attribute [StreamRendering(true)] and @rendermode InteractiveServer globally and should be setting it for each component? And this is a component, not a page setting - correct?

    If it's set on Routes, then that should override any child component settings.

    In essence, to run in old Server mode:

    1. Set the render mode on the root components in App.razor
    2. Add builder.Services.AddRazorComponents().AddInteractiveServerComponents() to services to add the necessary services.
    3. Add app.MapRazorComponents<Blazr.App.UI.Components.App>().AddInteractiveServerRenderMode() to set up the default page and InteractiveServer middleware to the Http request pipeline.

    And then forget about it.