Blazor Render modes
Inleiding
Microsoft heeft op 14 november 2023 .Net Core 8 uitgebracht.
In deze .Net-versie hebben ze ook Blazor onder handen genomen. Verschillende render modes kunnen vanaf nu in een Blazor-project gebruikt worden.
In deze post gaan we in op wat het ‘renderen’ ook alweer was en wat m.b.t het ‘renderen’ binnen Blazor mogelijk is.
Voor deze post gebruiken we de 17.8.3 Visual Studio 2022 upgrade en we bekijken het één en ander aan de hand van de voorbeeldpagina’s in de Visual Studio Blazor Web App-project template. De voorbeeldcode is terug te vinden in deze GitHub-repository.
Rendering
Het werkwoord ‘renderen’ staat voor weergeven of representeren. Voor een web applicatie komt het erop neer dat n.a.v. jouw verzoek via de browser een web server voor jou aan de slag gaat.
Alles wordt inclusief de gewenste gegevens door de web server “gerendered” (gerepresenteerd of weergegeven) naar HTML en vervolgens naar jouw browser gestuurd op je computer (zie ook deze post).
Blazor kent verschillende manieren om het één en ander te renderen waarbij volledig gebruik kan worden gemaakt van de server of zoveel mogelijk gebruik kan worden gemaakt van de browser op je PC (de client). Een tussenvorm is ook mogelijk waarbij, afhankelijk van de situatie alles eerst door de server wordt gedaan en daarna door de client.
Visual Studio
We lichten het één en ander toe aan de hand van de Visual Studio 2022 IDE. Microsoft heeft m.b.t. .Net 8 gekozen voor het doen üpgraden van Visual Studio 2022 en niet voor het gelijktijdig doen uitbrengen van een nieuwe versie van Visual Studio. Voor deze post gebruiken we de 17.8.3 VS 2022 upgrade.
Project templates
We hadden in het pre-.Net 8-tijdperk in Visual Studio de Blazor App-project-template en binnen die template moesten we kiezen tussen de Blazor Server App en de Blazor Web Assembly App (zie verder deze post om te zien hoe het toen was):
De Visual Studio 2022 IDE heeft sinds .Net 8 ook weer wat üpdates meegekregen. We hebben, naast de Blazor Server App– en de Blazor Web Assembly App nu ook de Blazor Web App-project template:
Blazor Web App-template
Met de Blazor Web App-project template kun je binnen je project verschillende render modes gebruiken. We zullen het één en ander toelichten aan de hand van die Blazor Web App-project template-project:
We willen binnen ons project gebruik maken van verschillende render modes. We selecteren bij de aanmaak van het project bij Interactive render mode dan ook optie Auto (Server and WebAssembly). Verder selecteren we voor de Interactivity Location optie Per page/component.
In onze solution zijn twee projecten aangemaakt. We hebben server project RenderModes en client project RenderModes.client.
We hebben bij de aanmaak van het project aangegeven dat we sample pages wilden hebben welke we bij de desbetreffende projecten zien.
We hebben voor deze post wat aanpassingen gedaan. Zo hebben we page Counter.razor in client project RenderModes.client herbenoemd naar Counter_client.razor en in server project RenderModes hebben we page Counter_server.razor toegevoegd.
Blazor kent een zogenaamde component model waarbij pages ook componenten zijn. Zie verder deze post voor meer uitleg over Blazor componenten.
Render modes
De volgende render modes zijn vanaf .Net 8 mogelijk:
- SSR (Server Side Rendering)
- Stream Rendering
- Interactive Server
- Interactive WebAssembly
- Interactive Auto
SSR (Server Side Rendering)
De Server Side Rendering mode (SSR) is de default binnen je Blazor project. Bij SSR wordt alles door de web server “gerendered” waarbij de browser een volledige HTML-pagina terugkrijgt. SSR is bedoeld voor situaties waarin gebruikersinteractie niet nodig is.
We lichten het één en ander toe aan de hand van component / scherm Weather.razor. De component vind je terug in server project RenderModes in folder Pages. We zetten in die component de StreamRendering uit zodat voor het renderen SSR wordt gebruikt:
@attribute [StreamRendering(false)]
In die component schroeven we de delay op naar vijf seconden. Een lang lopende Web API kunnen we daarmee beter simuleren:
/* Simulate asynchronous loading
to demonstrate streaming rendering */
await Task.Delay(5000)
Weather.razor simuleert een langlopende Web API dat vijf seconden nodig heeft voor het doen ophalen van het één en ander. Het scherm wordt gedurende de tijd dat Weather.razor bezig is (door te klikken op die menukeuze) bij SSR niet bijgewerkt. Het vorige scherm (van Home.razor – Hello, world!) of een leeg scherm wordt gedurende die vijf seconden getoond:
En de Web API is na vijf seconden klaar waarna de temperaturen op het scherm verschijnen:
SSR leent zich uitstekend voor statische pagina’s die weinig tot nooit veranderen en die geen interactie hebben met een gebruiker. Je zal je toevlucht moeten nemen tot extra JavaScript indien je SSR pagina toch een UI moet hebben met bijvoorbeeld invoervelden en buttons, maar wil je zoiets wel?
Blazor is ooit ontstaan omdat men minder tot geen JavaScript wilde gebruiken in een web applicatie. Andere render modes verdienen dan ook de voorkeur als iets met gebruikersinteractie gebouwd moet worden.
Stream Rendering
Stream Rendering is een uitbreiding op SSR en net als SSR bedoeld voor situaties zonder gebruikersinteractie. Bij Stream Rendering kan het verzoek naar de server opgedeeld worden in twee fasen.
De HTML wordt in de browser geladen (de eerste fase). Daarbij komen de nog niet gevulde placeholders ook mee. De gebruiker krijgt daardoor alvast wat te zien wat beter is dan een leeg scherm of een vorig scherm.
In fase twee van datzelfde verzoek wordt de (variabele) inhoud gestreamd naar de eerder ingeladen placeholders.
We lichten het één en ander toe aan de hand van component / scherm Weather.razor (terug te vinden in server project RenderModes in folder Pages). We zetten de StreamRendering aan in de component:
@attribute [StreamRendering(true)]
Als we in de code kijken van component / scherm Weather.razor dan is dit:
@if (forecasts == null { <p><em>Loading...</em><p> }
else ...
de placeholder:
De gebruiker krijgt gedurende de tijd dat Weather.razor bezig is dit te zien:
En de Web API is na vijf seconden klaar waarna de temperaturen op het scherm verschijnen:
We kijken met de browser developer tools of ergens een Web Socket SignalR-connectie wordt gemaakt. We zien geen web socket (WS) en dat is ook conform de verwachting.
Stream Rendering leent zich uitstekend voor bijvoorbeeld dashboards. De meeste dashboards bestaan uit een gedeelte met statische gegevens en een deel dat qua inhoud wel aan verandering onderhevig is.
De meeste dashboards hoeven ook geen gebruikersinteractie te hebben daar het vaak gaat om het tonen van gegevens die een gebruiker voor kennisgeving mag aannemen.
De gebruiker krijgt een betere ‘user experience’ met Stream Rendering. Een ‘Loading...’ of een ‘Bezig met‘-boodschap verschijnt gedurende de tijd dat de web applicatie bezig is met het inladen van de variabele gegevens.
Interactive Server
Men had in het pre-.Net 8-tijdperk de Blazor Server App. Een pre-.Net 8–Blazor Server App draaide op de server waarbij een SignalR-Web Socket-connectie het verkeer regelde tussen de client en de server en gebruikersinteractie ook mogelijk was.
Deze vorm van server side rendering met SignalR is nog steeds mogelijk en je moet daarvoor de InteractiveServer render mode gebruiken.
We hebben page / component Counter_server.razor toegevoegd aan server project RenderModes.
We geven als volgt op dat we gebruik willen maken van de InterActive Server render mode:
@rendermode RenderMode.InteractiveServer
En we zien met de browser developer tools dat er een Web Socket SignalR-connectie is gemaakt dat gebruikt wordt door page / component Counter_server.razor:
Blazor zal de default SSR render mode gebruiken als we niks opgeven voor de Render mode (je ziet in de browser developer tools dan ook geen Web Socket SignalR-connectie meer zodra je de page / component met SSR opstart):
Gebruikersinteractie is zonder JavaScript niet mogelijk in de SSR render mode. De page / component heeft verder geen JavaScript en de button zal in de SSR render mode niks doen.
Interactive WebAssembly
Bij een Blazor Web Assembly applicatie zal het merendeel van de code uitgevoerd worden in de browser door WebAssembly (WASM) en voor die code kan C# gebruikt worden. JavaScript hoef je daardoor weinig tot niet te gebruiken.
Blazor WebAssembly is (uiteraard) vanaf .Net 8 nog steeds mogelijk en je moet daarvoor de InteractiveWebAssembly render mode gebruiken:
@rendermode InteractiveWebAssembly
Een gebruikersinteractie is ook met Interactive Web Assembly mogelijk. De code voor o.a. de interactie in page / component Counter_server.client is C#-code en verder identiek aan de code in page / component Counter_server.razor.
De enige verschillen zitten in de render mode en de plek binnen de solution. Zo staat page Counter_client.razor in client project RenderModes.client en page Counter_server.razor staat in in server project RenderModes.
De C#-code zal in het geval van de client project uiteindelijk in de browser van de client draaien en in het geval van de server project op de server.
Bij de initiële start van een Blazor Web Assembly applicatie wordt (eenmalig) een hele bups aan .wasm– en .dll– bestanden overgezet naar de browser:
En via de browser developer tools zien we de aanwezigheid van WASM:
Interactive Auto
De keerzijde van WebAssembly is dat bij de initiële start van een Blazor Web Assembly applicatie eenmalig de .NET Runtime en allerlei bijbehorende bestanden gedownload worden naar de browser op de computer van de gebruiker. Dat kan dan weer leiden tot een lange opstarttijd met bijbehorende ‘bevroren’ schermen.
De lange opstarttijd bij een initiële start is blijkbaar toch een issue voor het doen gebruiken van WebAssembly. Microsoft heeft, om dit tegen te gaan, de Interactive Auto render mode in het leven geroepen. Je geeft dat als volgt op in je page / component als je die render mode wil gebruiken:
@rendermode InteractiveAuto
Bij de Interactive Auto render mode wordt bij een initiële opstart gebruik gemaakt van een Web Socket SignalR-connectie zodat de applicatie meteen gebruikt kan worden en de gebruiker geen last krijgt van ‘bevroren’ schermen tijdens de initiële download van de .NET Runtime en bijbehorende bestanden.
We zien via de browser developer tools niet alleen Wasm, maar ook een web socket:
De Interactive Auto render mode gebruikt de Web Socket SignalR-connectie niet meer na de initiële opstart. WASM kan het overnemen omdat alle benodigdheden voor WASM na die initiële opstart aanwezig zijn op de computer van de gebruiker waardoor een Web Socket SignalR-connectie niet meer nodig is.
Slot
Microsoft heeft op 14 november 2023 .Net Core 8 uitgebracht en verschillende render modes kunnen nu gebruikt worden in een Blazor-project. In deze post hebben we de render modes bekeken waarbij we gebruik hebben gemaakt van de voorbeeldpagina’s in de Visual Studio 2022 17.8.3 upgrade (project template Blazor Web App). De volgende render modes zijn vanaf .Net 8 mogelijk:
- SSR (Server Side Rendering)
- Stream Rendering
- Interactive Server
- Interactive WebAssembly
- Interactive Auto
SSR is de default render mode en het leent zich uitstekend voor statische pagina’s die weinig tot nooit veranderen en die geen interactie hebben met een gebruiker.
Stream Rendering is een uitbreiding op SSR en net als SSR bedoeld voor situaties zonder gebruikersinteractie. De gebruiker krijgt een betere ‘user experience’ met Stream Rendering. Een ‘Loading…’ of een ‘Bezig met’-boodschap verschijnt gedurende de tijd dat de web applicatie bezig is met het inladen van de variabele gegevens. Stream Rendering is met name geschikt voor zaken zoals dashboards daar dashboards meestal geen gebruikersinteractie hebben, maar wel gegevens bevatten die aan verandering onderhevig zijn.
Interactive Server (wat in het pre-.Net 8-tijdperk Blazor Server App werd genoemd) is een server render mode waarbij een SignalR-Web Socket-connectie het verkeer regelt tussen de client en de server en gebruikersinteractie ook mogelijk is. Interactive Server is geschikt als je uit kunt gaan van een permanente stabiele internet connectie en je het ook niet bezwaarlijk vindt dat er altijd een SignalR-Web Socket-connectie is naar en van de web server.
Bij een Blazor interactive WebAssembly applicatie wordt het merendeel van de code uitgevoerd in de browser door WebAssembly (WASM). Voor de code kan je ook C# gebruiken worden waardoor JavaScript minder tot niet nodig is. Verder is een permanente stabiele internet connectie geen vereiste voor een Blazor interactive WebAssembly applicatie. Een Blazor interactive WebAssembly applicatie kan zonder een internet connectie ook nog dingen doen.
De keerzijde van WebAssembly is dat bij de initiële start van een Blazor Web Assembly applicatie eenmalig de .NET Runtime en allerlei bijbehorende bestanden gedownload worden naar de browser op de computer van de gebruiker. Microsoft heeft, om die lange opstarttijd tegen te gaan de Interactive Auto render mode in het leven geroepen.
Bij de Interactive Auto render mode wordt bij een initiële opstart gebruik gemaakt van een Web Socket SignalR-connectie zodat de gebruiker geen last krijgt van een lange opstarttijd. Interactive WebAssembly gebruikt de Web Socket SignalR-connectie na de initiële opstart niet meer omdat alle benodigdheden voor WASM na de initiële opstart aanwezig zijn.
Microsoft heeft een goede stap gezet met het kunnen gebruiken van verschillende render modes in een Blazor-project. Je kan je web applicatie op die manier verder optimaliseren door voor iedere Blazor component een render mode te kiezen dat het meest bij de component past.
Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Klik op de Home-button om te zien wat ik nog meer geschreven heb…