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 artikelvoor 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 artikelvoor de huidige release.

In dit artikel worden scenario's voor prerendering van Razor-componenten voor server-gerenderde componenten in Blazor Web Apps uitgelegd.

Prerendering is het proces van het in eerste instantie weergeven van pagina-inhoud op de server zonder gebeurtenis-handlers in te schakelen voor gerenderde besturingselementen. De server voert de HTML-gebruikersinterface van de pagina zo snel mogelijk uit als reactie op de eerste aanvraag, waardoor de app sneller reageert op gebruikers. 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.

Vooraf samengestelde 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.

Overweeg de volgende PrerenderedCounter1 tellermodule. Het onderdeel stelt een eerste willekeurige tellerwaarde in tijdens prerendering in OnInitialized levenscyclus-methode. Nadat de SignalR verbinding met de client tot stand is gebracht, wordt het onderdeel opnieuw ingesteld en wordt de initiële tellingswaarde vervangen wanneer OnInitialized een tweede keer wordt uitgevoerd.

PrerenderedCounter1.razor:

@page "/prerendered-counter-1"
@rendermode @(new InteractiveServerRenderMode(prerender: true))
@inject ILogger<PrerenderedCounter1> Logger

<PageTitle>Prerendered Counter 1</PageTitle>

<h1>Prerendered Counter 1</h1>

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

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

@code {
    private int currentCount;

    protected override void OnInitialized()
    {
        currentCount = Random.Shared.Next(100);
        Logger.LogInformation("currentCount set to {Count}", currentCount);
    }

    private void IncrementCount() => currentCount++;
}

Voer de app uit en inspecteer logboekregistratie vanuit het onderdeel. Hier volgt een voorbeeld van uitvoer.

Notitie

Als de app gebruikmaakt van interactieve routering en de pagina wordt bereikt via een interne verbeterde navigatie, wordt er geen prerendering uitgevoerd. Daarom moet u een volledige pagina opnieuw laden voor het PrerenderedCounter1-onderdeel om de volgende uitvoer te zien. Zie de sectie Interactieve routering en prerendering voor meer informatie.

info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 41
info: BlazorSample.Components.Pages.PrerenderedCounter1[0]
currentCount set to 92

Het eerste geregistreerde aantal wordt vastgesteld tijdens de voorweergave. Het aantal wordt opnieuw ingesteld na het vooraf renderen wanneer het component opnieuw wordt gerenderd. Er is ook een flikkering in de gebruikersinterface wanneer het aantal wordt bijgewerkt van 41 naar 92.

Als u de initiële waarde van de teller tijdens het genereren wilt behouden, ondersteunt Blazor persistente status op een vooraf gegenereerde pagina met behulp van de PersistentComponentState-service (en voor onderdelen die zijn ingesloten in pagina's of weergaven van Razor Pagina's of MVC-apps, de Helper voor persistente onderdelenstatustags).

Als u de vooraf samengestelde status wilt behouden, bepaalt u welke status moet worden behouden met behulp van de PersistentComponentState-service. PersistentComponentState.RegisterOnPersisting registreert een callback om de onderdeelstatus te behouden voordat de app wordt onderbroken. De status wordt opgehaald wanneer de app wordt hervat.

In het volgende voorbeeld ziet u het algemene patroon:

  • De tijdelijke aanduiding {TYPE} vertegenwoordigt het type gegevens dat moet worden bewaard.
  • De aanduiding {TOKEN} is een string voor de status-id. Overweeg om nameof({VARIABLE})te gebruiken, waarbij de tijdelijke aanduiding {VARIABLE} de naam is van de variabele die de status bevat. Als u nameof() gebruikt voor de status-id, wordt het gebruik van een tekenreeks met aanhalingstekens vermeden.
@implements IDisposable
@inject PersistentComponentState ApplicationState

...

@code {
    private {TYPE} data;
    private PersistingComponentStateSubscription persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        persistingSubscription = 
            ApplicationState.RegisterOnPersisting(PersistData);

        if (!ApplicationState.TryTakeFromJson<{TYPE}>(
            "{TOKEN}", out var restored))
        {
            data = await ...;
        }
        else
        {
            data = restored!;
        }
    }

    private Task PersistData()
    {
        ApplicationState.PersistAsJson("{TOKEN}", data);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        persistingSubscription.Dispose();
    }
}

In het volgende voorbeeld van het tellerelement wordt de tellerstatus behouden tijdens het prerenderen en wordt de status opgehaald om het element te initialiseren.

PrerenderedCounter2.razor:

@page "/prerendered-counter-2"
@implements IDisposable
@inject ILogger<PrerenderedCounter2> Logger
@inject PersistentComponentState ApplicationState

<PageTitle>Prerendered Counter 2</PageTitle>

<h1>Prerendered Counter 2</h1>

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

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

@code {
    private int currentCount;
    private PersistingComponentStateSubscription persistingSubscription;

    protected override void OnInitialized()
    {
        persistingSubscription =
            ApplicationState.RegisterOnPersisting(PersistCount);

        if (!ApplicationState.TryTakeFromJson<int>(
            nameof(currentCount), out var restoredCount))
        {
            currentCount = Random.Shared.Next(100);
            Logger.LogInformation("currentCount set to {Count}", currentCount);
        }
        else
        {
            currentCount = restoredCount!;
            Logger.LogInformation("currentCount restored to {Count}", currentCount);
        }
    }

    private Task PersistCount()
    {
        ApplicationState.PersistAsJson(nameof(currentCount), currentCount);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose() => persistingSubscription.Dispose();

    private void IncrementCount() => currentCount++;
}

Wanneer het onderdeel wordt uitgevoerd, wordt currentCount slechts eenmaal ingesteld tijdens het prerenderen. De waarde wordt hersteld wanneer het onderdeel opnieuw wordt gebruikt. Hier volgt een voorbeeld van uitvoer.

Notitie

Als de app gebruikmaakt van interactieve routering en de pagina wordt bereikt via een interne verbeterde navigatie, wordt er geen prerendering uitgevoerd. Daarom moet u een volledige pagina opnieuw laden voor het PrerenderedCounter2-onderdeel om de volgende uitvoer te zien. Zie de sectie Interactieve routering en prerendering voor meer informatie.

info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount set to 96
info: BlazorSample.Components.Pages.PrerenderedCounter2[0]
currentCount restored to 96

Door onderdelen te initialiseren met dezelfde status die tijdens het prerenderen wordt gebruikt, worden dure initialisatiestappen slechts één keer uitgevoerd. De gerenderde gebruikersinterface komt ook overeen met de vooraf gegenereerde gebruikersinterface, dus er treedt geen flikkering op in de browser.

De persistente vooraf gegenereerde status wordt overgebracht naar de client, waar deze wordt gebruikt om de status van het onderdeel te herstellen. Tijdens het renderen aan de clientzijde (CSR, InteractiveWebAssembly), worden de gegevens blootgesteld aan de browser en mogen ze geen gevoelige, persoonlijke gegevens bevatten. Tijdens interactieve rendering aan de serverzijde (interactieve SSR, InteractiveServer), zorgt ASP.NET Core Data Protection ervoor dat de gegevens veilig worden overgedragen. De InteractiveAuto weergavemodus combineert WebAssembly en Server-interactiviteit, dus het is noodzakelijk om gegevensblootstelling in de browser te overwegen, zoals in het CSR-geval.

Onderdelen die zijn ingesloten in pagina's en weergaven (Razor Pagina's/MVC)

Voor componenten die zijn ingesloten in een pagina of weergave van een Razor Pages- of MVC-app, moet u de Persist Component State Tag Helper met de <persist-component-state /> HTML-tag binnen de sluitende </body>-tag van de lay-out van de app toevoegen. Dit is alleen vereist voor Razor Pages- en MVC-apps. Zie Helper voor persistente statustags voor onderdelen in ASP.NET Corevoor meer informatie.

Pages/Shared/_Layout.cshtml:

<body>
    ...

    <persist-component-state />
</body>

Interactieve routering en prerendering

Wanneer het Routes-onderdeel geen weergavemodus definieert, gebruikt de app interactiviteit en navigatie per pagina/onderdeel. Met navigatie per pagina/component wordt interne† navigatie afgehandeld door verbeterde routing nadat de app interactief wordt. †Intern in deze context betekent dat de URL-bestemming van de navigatie-gebeurtenis een Blazor eindpunt binnen de app is.

De PersistentComponentState-service werkt alleen bij het laden van de eerste pagina en niet bij interne verbeterde paginanavigatie-gebeurtenissen.

Als de app een volledige (niet-uitgebreide) navigatie naar een pagina uitvoert die gebruikmaakt van de status van een permanent onderdeel, wordt de persistente status beschikbaar gesteld voor de app die kan worden gebruikt wanneer deze interactief wordt.

Als er al een interactief circuit tot stand is gebracht en er een verbeterde navigatie wordt uitgevoerd op een pagina die gebruikmaakt van de permanente onderdeelstatus, wordt de status niet beschikbaar gesteld in het bestaande circuit voor het onderdeel omte gebruiken. Er is geen prerendering voor het interne paginaverzoek en de PersistentComponentState-service is zich er niet van bewust dat er een verbeterde navigatie heeft plaatsgevonden. Er is geen mechanisme om statusupdates te leveren aan onderdelen die al worden uitgevoerd op een bestaand circuit. De reden hiervoor is dat Blazor alleen ondersteuning biedt voor het doorgeven van de status van de server aan de client op het moment dat de runtime wordt geïnitialiseerd, niet nadat de runtime is gestart.

Voor .NET 10 (november 2025) wordt extra werk verricht aan het Blazor framework om dit scenario aan te pakken. Voor meer informatie en communitydiscussie over niet-ondersteunde tijdelijke oplossingen‡, zie Permanente onderdeelstatus ondersteunen voor uitgebreide paginanavigatie (dotnet/aspnetcore #51584). ‡Niet-ondersteunde tijdelijke oplossingen worden niet goedgekeurd door Microsoft voor gebruik in Blazor-apps. Gebruik pakketten, benaderingen en code van derden op eigen risico.

Verbeterde navigatie uitschakelen, waardoor de prestaties worden verminderd, maar ook het probleem van de laadstatus met PersistentComponentState voor interne paginaaanvragen wordt vermeden, wordt behandeld in ASP.NET Core Blazor routering en navigatie.

Richtlijnen voor prerendering

Prerenderingsrichtlijnen zijn ingedeeld in de Blazor documentatie per onderwerp. De volgende koppelingen hebben betrekking op alle prerenderingsrichtlijnen in de documentatie, gesorteerd op onderwerp.