Routing statico e PreRendering in una Blazor Web App

di Marco De Sanctis, in ASP.NET Core,

Negli script precedenti abbiamo introdotto il nuovo concetto di Render Mode in una Blazor Web App di Blazor 8 e abbiamo visto come in questo tipo di applicazione possiamo combinare i tre tipi di rendering (Static, InteractiveServer e InteractiveWebAssembly) tutto sommato in maniera abbastanza trasparente.

Tuttavia, questo sistema di rendering flessibile, ha un importante impatto anche a livello di routing.

Prendiamo come esempio l'applicazione di default, che possiamo generare via template, con le impostazioni seguenti:

dotnet new blazor -n SampleInteractive -int WebAssembly

Come abbiamo visto nello scorso script, questo template genera due progetti, uno server e uno client, con quest'ultimo contenente la pagina Counter in modalità WebAssembly:

@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
  ..
}

Intuitivamente, ci aspetteremmo che questo componente funzioni esclusivamente client side, ossia solo sul browser. Tuttavia non è questo il caso, e per dimostrarlo possiamo inserire un messaggio di log su OnInitialized:

protected override void OnInitialized()
{
    base.OnInitialized();

    Console.WriteLine("Counter.OnInitialized");
}

Proviamo ora a eseguire l'applicazione, e con nostra sorpresa noteremo che il messaggio "Counter.OnInitialized" appare due volte: una, come ci aspetteremmo, sulla finestra di log del browser, ma è anche visibile nella Console Application del server:


Questo accade perché si verificano due condizioni:

  • Il componente counter ha il PreRendering attivo per default
  • L'applicazione sta utilizzando il routing statico

La condizione di routing statico, in particolare, è definita dall'elemento Routes nella pagina App.razor:

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

Siccome non abbiamo specificato alcun RenderMode, per default il routing utilizza lo static render mode, che comporta che ogni URL, anche durante la navigazione sul sito, sia richiesto direttamente al server. Questo avviene a prescindere dal fatto che abbiamo specificato che Counter sia un componente WebAssembly, perché, come abbiamo accennato, tutti i componenti hanno il PreRendering attivo per default.

Questa logica può generare comportamenti ed errori inaspettati, quali flickering o eccezioni sulla dependency injection.

Per esempio, immaginiamo che Counter necessiti di un servizio ICounterInitializer. Dato che il componente viene eseguito due volte, una lato server e una lato client, dovremo essere sicuri di avere registrato l'implementazione di ICounterInitializer in entrambi gli IoC container, altrimenti otterremo un errore come quello in basso:


Il modo più semplice per ovviare a questo problema, è quello di disabilitare il PreRendering per il Counter, anche in virtù del fatto che questa funzionalità non è che sia così utile per il componente in questione:

@page "/counter"
@rendermode @(new InteractiveWebAssemblyRenderMode(prerender:false))

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

In altre situazioni, invece, soprattutto per ragioni di Search Engine Optimisation (ma non solo), potrebbe essere utile mantenere attivo il PreRendering. In questo caso ci sono delle considerazioni che dovremo fare, di cui ci occuperemo in un prossimo script.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi