Udostępnij za pomocą


Składniki wstępnego renderowania ASP.NET Core Razor

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.

W tym artykule opisano Razor scenariusze prerenderowania składników dla składników renderowanych przez serwer w Blazor Web App systemach i Blazor Server aplikacjach.

Prerendering to proces statycznego renderowania zawartości strony z serwera w celu jak najszybszego dostarczenia kodu HTML do przeglądarki. Po szybkim wyświetleniu zawartości wstępnie zdefiniowanej użytkownikowi interaktywna zawartość z aktywnymi procedurami obsługi zdarzeń zostanie wyrenderowana, zastępując dowolną zawartość, która została wcześniej renderowana. Prerendering może również poprawić optymalizację dla wyszukiwarek internetowych (SEO) przez renderowanie treści w początkowej odpowiedzi HTTP, której używają wyszukiwarki do obliczania rangi strony.

Prerendering jest domyślnie włączony dla składników interaktywnych.

Nawigacja wewnętrzna z routingiem interakcyjnym nie używa prerenderingu, ponieważ strona jest już interaktywna. Aby uzyskać więcej informacji, zobacz Routing statyczny i interakcyjnyoraz Routing interakcyjny i prerendering.

OnAfterRender{Async} Zdarzenia cyklu życia składnika nie są wywoływane w przypadku prerenderingu, tylko po interakcyjnym renderowaniu składnika.

Wyłączanie prerenderingu

Wstępne renderowanie może komplikować aplikację, ponieważ składniki aplikacji Razor muszą być renderowane dwa razy: raz na potrzeby wstępnego opracowywania i raz na potrzeby konfigurowania interakcyjności. Jeśli składniki są skonfigurowane do uruchamiania w zestawie WebAssembly, należy również zaprojektować składniki, aby mogły być uruchamiane zarówno z serwera, jak i klienta.

Aby wyłączyć prerendering dla wystąpienia składnika, przekaż flagę prerender z wartością false do trybu renderowania.

  • <... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
  • <... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />

Aby wyłączyć prerendering w definicji komponentu:

  • @rendermode @(new InteractiveServerRenderMode(prerender: false))
  • @rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
  • @rendermode @(new InteractiveAutoRenderMode(prerender: false))

Aby wyłączyć wstępne przetwarzanie dla całej aplikacji, wskaż tryb renderowania na najwyższym poziomie składnika interaktywnego w hierarchii składników aplikacji, który nie jest składnikiem głównym.

W przypadku aplikacji opartych na szablonie Blazor Web App projektu tryb renderowania przypisany do całej aplikacji jest określony, gdzie Routes składnik jest używany w składniku App (Components/App.razor). W poniższym przykładzie ustawiono tryb renderowania aplikacji na Serwer interaktywny z wyłączonym prerenderingem.

<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />

Dodatkowo, wyłącz prerendering dla składnika HeadOutlet w składniku App.

<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />

Tworzenie interaktywnego składnika głównego, takiego jak składnik App, za pomocą dyrektywy @rendermode znajdującej się na górze pliku definicji składnika głównego (.razor) nie jest obsługiwane. W związku z tym prerendering nie może być bezpośrednio wyłączony przez komponent App.

Wyłączenie prerenderingu przy użyciu powyższych technik ma zastosowanie tylko dla trybów renderowania najwyższego poziomu. Jeśli składnik nadrzędny określa tryb renderowania, ustawienia wstępne jego elementów podrzędnych są ignorowane.

Zachowaj stan wstępnie renderowany

Bez utrwalania stanu wstępnego, stan używany podczas prerenderingu jest utracony i musi zostać utworzony ponownie, gdy aplikacja jest w pełni załadowana. Jeśli jakikolwiek stan jest tworzony asynchronicznie, interfejs użytkownika może migać, ponieważ wcześniej wyrenderowany interfejs użytkownika jest zastępowany, gdy składnik jest ponownie renderowany. Aby uzyskać wskazówki dotyczące utrwalania stanu podczas wstępnego renderowania, zobacz utrwalanie stanu wstępnie wyrenderowanego w ASP.NET CoreBlazor.

Nie można rozpoznać usług po stronie klienta podczas wstępnego renderowania

Zakładając, że prerendering nie jest wyłączony dla składnika lub aplikacji, składnik w projekcie .Client jest prerenderowany na serwerze. Ponieważ serwer nie ma dostępu do zarejestrowanych usług po stronie Blazor klienta, nie można wstrzyknąć tych usług do składnika bez otrzymania błędu wskazującego na niemożność odnalezienia usługi podczas prerenderowania.

Na przykład, rozważmy następujący Home składnik w projekcie .Client w ramach Blazor Web App z globalnym interaktywnym WebAssembly lub automatycznym interaktywnym renderowaniem. Składnik próbuje wstrzyknąć IWebAssemblyHostEnvironment, aby uzyskać nazwę środowiska.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

<p>
    Environment: @Environment.Environment
</p>

Podczas prerenderingu nie występuje błąd czasu kompilacji, ale występuje błąd środowiska uruchomieniowego:

Nie można podać wartości właściwości "Environment" dla typu "BlazorSample.Client.Pages".Home Nie ma zarejestrowanej usługi typu "Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment".

Ten błąd występuje, ponieważ składnik musi kompilować i wykonywać na serwerze podczas prerenderingu, ale IWebAssemblyHostEnvironment nie jest zarejestrowaną usługą na serwerze.

Rozważ dowolne z następujących podejść, aby rozwiązać ten scenariusz:

Rejestracja usługi zarówno na serwerze, jak i na kliencie.

Jeśli usługa obsługuje wykonywanie na serwerze, zarejestruj ją zarówno na serwerze, jak i na kliencie, aby była dostępna podczas prerenderingu. Aby zapoznać się z przykładem tego scenariusza, zobacz wytyczne dotyczące HttpClient usług w sekcji Blazor Web App artykułu Wywoływanie internetowego interfejsu API.

Wstrzykiwanie usługi, która może być używana przez aplikację podczas prerenderingu

W niektórych przypadkach aplikacja może używać usługi na serwerze podczas prerenderingu i innej usługi na kliencie.

Na przykład poniższy kod uzyskuje środowisko aplikacji niezależnie od tego, czy kod jest uruchomiony na serwerze, czy na kliencie przez wstrzyknięcie IHostEnvironment z Microsoft.Extensions.Hosting.Abstractions pakietu NuGet:

private string? environmentName;

public Home(IHostEnvironment? serverEnvironment = null, 
    IWebAssemblyHostEnvironment? wasmEnvironment = null)
{
    environmentName = serverEnvironment?.EnvironmentName;
    environmentName ??= wasmEnvironment?.Environment;
}

Jednak takie podejście dodaje dodatkową zależność do projektu klienta, który nie jest potrzebny.

Ustaw usługę jako opcjonalną

Ustaw usługę jako opcjonalną, jeśli nie jest wymagana podczas prerenderingu przy użyciu jednej z poniższych metod.

W poniższym przykładzie użyto iniekcji konstruktora IWebAssemblyHostEnvironment:

private string? environmentName;

public Home(IWebAssemblyHostEnvironment? env = null)
{
    environmentName = env?.Environment;
}

Możesz też zaimplementować IServiceProvider, żeby opcjonalnie uzyskać usługę, jeśli jest dostępna.

@page "/"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IServiceProvider Services

<PageTitle>Home</PageTitle>

<h1>Home</h1>

<p>
    <b>Environment:</b> @environmentName
</p>

@code {
    private string? environmentName;

    protected override void OnInitialized()
    {
        if (Services.GetService<IWebAssemblyHostEnvironment>() is { } env)
        {
            environmentName = env.Environment;
        }
    }
}

Tworzenie abstrakcji usługi

Jeśli na serwerze potrzebna jest inna implementacja usługi, utwórz abstrakcję usługi i utwórz implementacje dla usługi w projektach serwera i klienta. Zarejestruj usługi w każdym projekcie. Jeśli to konieczne, wprowadź abstrakcję niestandardowej usługi do składników. Następnie składnik zależy wyłącznie od dostosowanej abstrakcji serwisu.

W przypadku programu IWebAssemblyHostEnvironmentmożemy ponownie użyć istniejącego interfejsu zamiast tworzyć nowe:

ServerHostEnvironment.cs:

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Components;

public class ServerHostEnvironment(IWebHostEnvironment env, NavigationManager nav) : 
    IWebAssemblyHostEnvironment
{
    public string Environment => env.EnvironmentName;
    public string BaseAddress => nav.BaseUri;
}

W pliku projektu Program serwera zarejestruj usługę:

builder.Services.TryAddScoped<IWebAssemblyHostEnvironment, ServerHostEnvironment>();

W tym momencie usługę IWebAssemblyHostEnvironment można wstrzykiwać do interaktywnego składnika WebAssembly lub Auto, który jest również wstępnie renderowany z serwera.

Wyłączanie prerenderingu dla składnika

Wyłącz wstępne renderowanie składnika lub całej aplikacji. Aby uzyskać więcej informacji, zobacz sekcję Wyłączanie prerenderingu .