Delen via


Prerender ASP.NET Core Razor-componenten

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikel voor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikel voor de huidige release.

In dit artikel worden scenario's voor het voorbereiden van onderdelen voor server gerenderde onderdelen in Razors en Blazor Web App apps uitgelegdBlazor Server.

Prerendering is het proces van het statisch weergeven van pagina-inhoud van de server om HTML zo snel mogelijk aan de browser te leveren. Nadat de vooraf gegenereerde inhoud snel aan de gebruiker wordt weergegeven, wordt interactieve inhoud met actieve gebeurtenis-handlers weergegeven, waarbij alle eerder weergegeven inhoud wordt vervangen. Prerendering kan ook seo (Search Engine Optimization) verbeteren door inhoud weer te geven voor het eerste HTTP-antwoord dat zoekmachines gebruiken om de paginarang te berekenen.

Prerendering is standaard ingeschakeld voor interactieve onderdelen.

Interne navigatie met interactieve routering gebruikt geen prerendering omdat de pagina al interactief is. Zie Statisch versus interactieve routering en interactieve routering en prerendering voor meer informatie.

OnAfterRender{Async} levenscyclusgebeurtenissen van onderdelen worden niet aangeroepen wanneer ze worden voorbereid, alleen nadat het onderdeel interactief wordt weergegeven.

Prerendering uitschakelen

Prerendering kan een app bemoeilijken omdat de onderdelen van Razor de app twee keer moeten worden weergegeven: één keer voor het voorbereiden en één keer voor het instellen van interactiviteit. Als de onderdelen zijn ingesteld voor uitvoering op WebAssembly, moet u ook uw onderdelen ontwerpen zodat ze kunnen worden uitgevoerd vanaf zowel de server als de client.

Wilt u de prerendering uitschakelen voor een componentinstantie, geef dan de vlag prerender met een waarde van false door aan de weergavemodus:

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

Prerendering uitschakelen in een componentdefinitie:

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

Als u het prerendering voor de hele app wilt uitschakelen, geeft u de rendermodus op het hoogste niveau aan in de componenthiërarchie van de app die geen hoofdonderdeel is.

Voor apps op basis van de Blazor Web App projectsjabloon wordt een weergavemodus opgegeven die is toegewezen aan de hele app, waarbij het Routes onderdeel wordt gebruikt in het App onderdeel (Components/App.razor). In het volgende voorbeeld wordt de rendermodus van de app ingesteld op Interactive Server, waarbij de prerendering is uitgeschakeld:

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

Schakel ook het prerendering uit voor het HeadOutlet-onderdeel in het App-onderdeel:

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

Het maken van een hoofdonderdeel, zoals het App-onderdeel, interactief met de @rendermode instructie boven aan het definitiebestand van het hoofdonderdeel (.razor) wordt niet ondersteund. Daarom kan prerendering niet rechtstreeks worden uitgeschakeld door het App onderdeel.

Het uitschakelen van prerendering met behulp van de voorgaande technieken wordt alleen van kracht voor rendermodi op het hoogste niveau. Als een oudercomponent een weergavemodus opgeeft, worden de prerenderingsinstellingen van de kindcomponenten genegeerd.

Voorgeconfigureerde status behouden

Zonder dat de vooraf gegenereerde status behouden blijft, gaat de status die tijdens het prerenderen wordt gebruikt verloren en moet deze opnieuw worden gemaakt wanneer de app volledig is geladen. Als er asynchroon een status wordt gemaakt, kan de gebruikersinterface flikkeren als de vooraf gegenereerde gebruikersinterface wordt vervangen wanneer het onderdeel opnieuw wordt uitgevoerd. Zie ASP.NET Core Blazor prerendered state persistence voor hulp bij het behouden van de status tijdens het prerendering.

Klantsideservices falen om te worden opgelost tijdens prerenderen

Ervan uitgaande dat prerendering niet is uitgeschakeld voor een component of voor de app, wordt een component in het .Client-project op de server gerenderd. Omdat de server geen toegang heeft tot client-side geregistreerde Blazor services, is het niet mogelijk om deze services in een onderdeel te injecteren zonder een foutmelding te krijgen dat de service niet kan worden gevonden tijdens het prerenderen.

Denk bijvoorbeeld aan het volgende Home onderdeel in het .Client project in een Blazor Web App met globale interactieve WebAssembly of interactieve automatische weergave. Het onderdeel probeert IWebAssemblyHostEnvironment te injecteren om de naam van de omgeving te verkrijgen.

@page "/"
@inject IWebAssemblyHostEnvironment Environment

<PageTitle>Home</PageTitle>

<h1>Home</h1>

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

Er treedt geen compileertijdfout op, maar er treedt een runtimefout op tijdens het prerendering:

Kan geen waarde opgeven voor eigenschap 'Environment' voor het type BlazorSample.Client.Pages.Home'. Er is geen geregistreerde service van het type Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment.

Deze fout treedt op omdat het onderdeel tijdens het prerenderen op de server moet compileren en uitvoeren, maar IWebAssemblyHostEnvironment geen geregistreerde service op de server is.

Houd rekening met een van de volgende benaderingen om dit scenario aan te pakken:

Registreer de service op de server naast de client

Als de service ondersteuning biedt voor serveruitvoering, registreert u de service op de server naast de client, zodat deze beschikbaar is tijdens het voorbereiden. Zie de richtlijnen voor HttpClient services in de Blazor Web App sectie Externe web-API's van het artikel Web-API aanroepen voor een voorbeeld van dit scenario.

Een service invoegen die de app kan gebruiken tijdens het vooraf renderen.

In sommige gevallen kan de app een service op de server gebruiken tijdens de prerendering en een andere service op de client.

Met de volgende code wordt bijvoorbeeld de omgeving van de app opgehaald, ongeacht of de code wordt uitgevoerd op de server of op de client door deze vanuit het Microsoft.Extensions.Hosting.Abstractions te injecteren:

private string? environmentName;

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

Met deze benadering wordt echter een extra afhankelijkheid toegevoegd aan het clientproject dat niet nodig is.

De service optioneel maken

Maak de service optioneel als deze niet is vereist tijdens het prerendering met behulp van een van de volgende methoden.

In het volgende voorbeeld wordt gebruikgemaakt van constructorinjectie van IWebAssemblyHostEnvironment:

private string? environmentName;

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

U kunt ook injecteren IServiceProvider om de service optioneel te verkrijgen als deze beschikbaar is:

@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;
        }
    }
}

Een serviceabstractie maken

Als er een andere service-implementatie nodig is op de server, maakt u een serviceabstractie en maakt u implementaties voor de service in de server- en clientprojecten. Registreer de diensten in ieder project. Injecteer de aangepaste service-abstractie in componenten waar nodig. Het onderdeel is vervolgens afhankelijk van alleen de aangepaste service-abstractie.

In het geval van IWebAssemblyHostEnvironment, kunnen we de bestaande interface opnieuw gebruiken in plaats van een nieuwe te maken:

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;
}

Registreer de service in het Program bestand van het serverproject.

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

Op dit moment kan de IWebAssemblyHostEnvironment service worden geïnjecteerd in een interactief WebAssembly- of Auto-onderdeel dat ook vooraf op de server is gerenderd.

Prerendering voor het onderdeel uitschakelen

Prerendering uitschakelen voor het onderdeel of voor de hele app. Zie de sectie Prerendering uitschakelen voor meer informatie.