Dela via


Komponenter i Prerender ASP.NET Core Razor

Anteckning

Det här är inte den senaste versionen av den här artikeln. För den aktuella utgåvan, se .NET 9-versionen av den här artikeln.

Viktig

Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.

För den aktuella utgåvan, se .NET 9-versionen av den här artikeln.

Den här artikeln beskriver Razor scenarier för komponentförbevarande för serveråtergivna komponenter i Blazor Web Apps.

Prerendering är processen att först återge sidinnehåll på servern utan att aktivera händelsehanterare för renderade kontroller. Servern matar ut HTML-användargränssnittet på sidan så snart som möjligt som svar på den första begäran, vilket gör att appen känns mer dynamisk för användarna. Prerendering kan också förbättra sökmotoroptimering (SEO) genom att återge innehåll för det första HTTP-svaret som sökmotorer använder för att beräkna sidrankning.

Bevara fördefinierat tillstånd

Utan att det förinstallerade tillståndet bevaras går tillståndet som används under förinläsningen förlorat och måste återskapas när appen är helt inläst. Om något tillstånd skapas asynkront kan användargränssnittet flimra när det förinstallerade användargränssnittet ersätts när komponenten återställs.

Överväg följande PrerenderedCounter1 räknarkomponent. Komponenten anger ett första slumpmässigt räknarvärde under förinläsning i OnInitialized livscykelmetod. När SignalR-anslutningen till klienten har upprättats, renderas komponenten på nytt och det initiala antalsvärdet ersätts när OnInitialized utförs en andra gång.

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

Kör appen och inspektera loggning från komponenten. Följande är exempelutdata.

Anteckning

Om appen implementerar interaktiv routning och sidan nås via en intern förbättrad navigeringsker inte prerendering. Därför måste du utföra en fullständig sidåterläsning för PrerenderedCounter1-komponenten för att se följande resultat. Mer information finns i avsnittet Interaktiv routning och prerendering.

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

Det första loggade antalet inträffar under prerendering. Antalet anges igen efter prerendering när komponenten har återskapats. Det finns också ett flimmer i användargränssnittet när antalet uppdateras från 41 till 92.

För att behålla räknarens initiala värde under förpresentationen stöder Blazor beständighet av tillstånd på en förrenderad sida med hjälp av PersistentComponentState-tjänsten (och för komponenter som är inbäddade i sidor eller vyer av Razor Pages- eller MVC-appar, Persist Component State Tag Helper).

Om du vill bevara förinstallerat tillstånd bestämmer du vilket tillstånd som ska sparas med hjälp av PersistentComponentState-tjänsten. PersistentComponentState.RegisterOnPersisting registrerar ett återanrop för att bevara komponenttillståndet innan appen pausas. Tillståndet hämtas när appen återupptas.

I följande exempel visas det allmänna mönstret:

  • Platshållaren {TYPE} representerar den typ av data som ska sparas.
  • Platshållaren {TOKEN} är en tillståndsidentifierarsträng. Överväg att använda nameof({VARIABLE}), där platshållaren {VARIABLE} är namnet på variabeln som innehåller tillståndet. Om du använder nameof() för tillståndsidentifieraren undviks användningen av en citerad sträng.
@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();
    }
}

Följande exempel på räknarkomponenten bevarar räknartillståndet under förinläsningen och hämtar tillståndet för att initiera komponenten.

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

När komponenten körs anges currentCount endast en gång under förberedande rendering. Värdet återställs när komponenten återställs. Följande är exempelutdata.

Anteckning

Om appen implementerar interaktiv routning och sidan nås via en intern förbättrad navigeringsker inte prerendering. Därför måste du utföra en fullständig sidåterläsning för PrerenderedCounter2-komponenten för att se följande resultat. Mer information finns i avsnittet Interaktiv routning och prerendering.

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

Genom att initiera komponenter med samma tillstånd som används under förinläsningen körs eventuella dyra initieringssteg bara en gång. Det renderade användargränssnittet matchar också det förinstallerade användargränssnittet, så inget flimmer förekommer i webbläsaren.

Det beständiga förinstallerade tillståndet överförs till klienten, där det används för att återställa komponenttillståndet. Under återgivning på klientsidan (CSR, InteractiveWebAssembly) exponeras data i webbläsaren och får inte innehålla känslig, privat information. Under interaktiv återgivning på serversidan (interaktiv SSR, InteractiveServer), säkerställer ASP.NET Core Data Protection att data överförs på ett säkert sätt. Återgivningsläget InteractiveAuto kombinerar WebAssembly och serverinteraktivitet, så det är viktigt att beakta dataexponeringen för webbläsaren, som i fallet med CSR.

Komponenter inbäddade i sidor och vyer (Razor Pages/MVC)

För komponenter som är inbäddade i en sida eller vy av en Razor Pages- eller MVC-app måste du lägga till Spara komponenttillståndstaggen med <persist-component-state /> HTML-taggen i den avslutande </body> taggen i appens layout. Detta krävs endast för Razor Pages- och MVC-appar. Mer information finns i Persist Component State Tag Helper in ASP.NET Core.

Pages/Shared/_Layout.cshtml:

<body>
    ...

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

Interaktiv routning och prerendering

När den Routes komponenten inte definierar ett återgivningsläge använder appen interaktivitet och navigering per sida/komponent. Genom att använda navigering per sida/komponent hanteras intern† navigering av förbättrad ruttning efter att appen blivit interaktiv. †Intern i den här kontexten innebär att URL-målet för navigeringshändelsen är en Blazor slutpunkt i appen.

Tjänsten PersistentComponentState fungerar bara vid den inledande sidinläsningen och inte vid förbättrade interna sidnavigeringshändelser.

Om appen utför en fullständig (icke-utökad) navigering till en sida med beständiga komponenttillstånd görs det beständiga tillståndet tillgängligt för appen att använda när den blir interaktiv.

Om en interaktiv krets redan har upprättats och en förbättrad navigering utförs på en sida med beständiga komponenttillstånd, görs inte tillståndet tillgängligt i den befintliga kretsen för komponenten att använda. Det finns ingen prerendering för den interna sidbegäran och PersistentComponentState-tjänsten är inte medveten om att en förbättrad navigering har inträffat. Det finns ingen mekanism för att leverera tillståndsuppdateringar till komponenter som redan körs på en befintlig krets. Anledningen till detta är att Blazor endast stöder överföring av tillstånd från servern till klienten när körtiden initieras, inte efter att körtiden har startat.

Ytterligare arbete med det Blazor ramverket för att hantera det här scenariot övervägs för .NET 10 (november 2025). Mer information och community-diskussion om lösningar som inte stöds‡finns i Support persistent component state across enhanced page navigations (dotnet/aspnetcore #51584). ‡Lösningar som inte stöds sanktioneras inte av Microsoft för användning i Blazor appar. Använd paket, metoder och kod från tredje part på egen risk.

Att inaktivera förbättrad navigering, vilket minskar prestanda men undviker också problemet med inläsningstillståndet med PersistentComponentState för interna sidbegäranden, beskrivs i ASP.NET Core Blazor routning och navigering.

Vägledning för förberendering

Vägledning för föråtergivning organiseras i Blazor-dokumentationen efter ämnesområde. Följande länkar täcker all vägledning för förberendering i dokumentationen efter ämne: