Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
vermeir_nico_introducing_net_6_getting_started_with_blazor_m.pdf
Скачиваний:
19
Добавлен:
26.06.2023
Размер:
11.64 Mб
Скачать

Chapter 5 Blazor

A total of 9.7 MB was downloaded; this was the first launch of that specific application. Figure 5-10 shows the same metric, but after launching the app for a second time.

Figure 5-10.  Launching the app again

Launching the app again takes significantly less time and resources. That is because the browser caches as much as possible. There’s even quite a big chance that your users won’t notice the three seconds it takes to load your application. That is because there is a big difference between speed and the perception of speed. As mentioned before, the first thing loaded into the browser is the index.html file. That file contains logic to show “Loading…,” while the WASM and .NET runtimes are being downloaded and started; replace that with a nice loading animation, and your application will be perceived as loading quite fast.

Blazor Server

Blazor Server is a second flavor of Blazor. It looks and feels very similar to Blazor WASM, but the big difference is in the underlying architecture. Instead of running inside web assembly, it actually runs on a server, hence the name. Blazor server uses a SignalR connection to send requests to a server that handles all the instructions and sends back changes to the DOM. Before we go any deeper, let’s see what SignalR is.

SignalR

SignalR has been around for quite some years. It is a framework that allows developers to easily implement real-time communication between clients and servers. It enables server code to directly call methods on clients instead of clients having to poll for data on the server. A simple example of this is a chat application where client A pushes

a new message to the server; the server then calls client B with the new message as parameter. All of this is possible due to Websockets, which is the underlying mechanism of SignalR. But it goes one step further. On platforms that don’t support Websockets,

144

Chapter 5 Blazor

SignalR can automatically fall back to older transport protocols. Because of this fallback functionality and a load of abstractions on top of the Websockets, API SignalR has quickly gained a lot of popularity.

Thanks to SignalR we have server–client and client–server communication. By leveraging this, Microsoft built a server-based web framework that does not do page reloads; instead, they receive a piece of DOM through the SignalR connection. We can see this in action by launching the counter page of the default Blazor Server template. The project template is mostly the same as Blazor WASM, from App.razor to MainLayout down to the code of the components. Just like in Blazor WASM, when you inspect the HTML code and click the counter button, you will see that only the element containing the number is updated; the rest of the page is never reloaded.

There are a few differences in how Blazor Server launches compared to Blazor WASM. Let’s start at the main entrance point of the application, Program.cs.

Listing 5-12.  Program.cs from a Blazor Server application

var builder = WebApplication.CreateBuilder(args);

// Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton<WeatherForecastService>();

var app = builder.Build();

// Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment())

{

app.UseExceptionHandler("/Error");

//The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

app.UseHsts();

}

145

Chapter 5 Blazor

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.MapBlazorHub(); app.MapFallbackToPage("/_Host");

app.Run();

Program.cs in .NET 6 contains top-level statements once again, making for a cleaner file without a class declaration. If you’ve used ASP.NET MVC before, the instructions in this file might look very familiar. That is because the SignalR connection is powered by ASP.NET, so we need to bootstrap that framework as well. Similar to Blazor WASM, we start by registering services in the built-in dependency injection (DI). After registering services, we have basic boilerplate code to enable HTTPS, set up routing, and start

the app.

There are two Blazor-specific calls in this file. The first one is builder. Services.AddServerSideBlazor();. This call registers Blazor-specific services into the DI container, services like the NavigationManager for navigation between Razor components or the IJSRuntime to enable JavaScript interop. The exact code of this method can be found on GitHub https://github.com/dotnet/ aspnetcore/blob/main/src/Components/Server/src/DependencyInjection/

ComponentServiceCollectionExtensions.cs. The second Blazor-specific call is app. MapBlazorHub();. This call opens the connection to the Blazor SignalR hub. A SignalR hub is a class that contains communication logic between clients and a SignalR server. In this case, the hub will contain the logic that enables receiving instructions and data from a client, generating a DOM diff and sending it back to the client. The SignalR part of Blazor Server is also open sourced on GitHub at ­https://github.com/dotnet/ aspnetcore/tree/main/src/Components/Server/src/BlazorPack.

Another difference from Blazor WASM is the absence of the index.html page from the wwwroot folder; instead, there is a _Host.cshtml file in the Pages folder of the project. Files with the cshtml extension are ASP.NET webpages; since Blazor Server has need for a webserver that supports .NET, we can leverage the power of ASP.NET as well. The

_Host.cshtml file is mostly HTML 5 with a namespace and a routing attribute. But it does contain an interesting line that impacts the entire application.

146

Chapter 5 Blazor

Listing 5-13.  Rendering mode in Blazor Server

<component type="typeof(App)" render-mode="ServerPrerendered" />

The component tag specifies where in the host file our actual Blazor application will get rendered. The type parameter sets the startup type of the app. The render mode will specify where the application is rendered and how dynamic it can be. There are three options.

•\

Static: All components are rendered into static HTML, meaning that

 

there is no connection to a Blazor SignalR server and pages have no

 

Blazor functionality.

•\

Server: The webserver builds the HTML, connects to SignalR, and

 

activates all Blazor functionality. After the server is finished with all

 

that, the browser will receive the HTML and render everything. This

 

is the slowest option but with the most consistent results.

•\

ServerPrerendered: This option uses a technique called hydration.

 

Hydration is a known pattern in most popular SPA frameworks; it

 

takes the best of both static and server render modes to find a middle

 

ground between performance and functionality. Hydration is a two-­

 

step process; the first step renders static HTML which gives users

 

the illusion of a fast page load. At this point, the page has appeared

 

on screen but there is no Blazor functionality. In the second step,

 

there is a piece of JavaScript in blazor.server.js that will open the

 

connection to the SignalR hub and hydrate the already rendered page

 

with functionality; the page basically re-renders invisible to the user.

 

The blazor.server.js file is a file included in the Microsoft.AspNetCore.

 

Components.Server.dll assembly. It gets injected in your application’s

 

output automatically.

ServerPrerendered is the default option, and looking from an end-user perspective, it is the most interesting one performance vs. functionality-wise. However, do be careful with automated tests. We have run into issues where the test runner is clicking a button before the re-rendering has taken place. The re-rendering usually happens fast, from a human perspective. Automated tests are executed by machines and can happen faster than the re-rendering.

147