Freigeben über


Vorabrendern von ASP.NET Core Razor-Komponenten

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

In diesem Artikel werden Szenarien zum Voarabrendering von Razor-Komponenten für serverseitige gerenderte Komponenten in Blazor Web Apps erläutert.

Prerendering ist der Prozess des anfänglichen Renderns von Seiteninhalten auf dem Server, ohne Ereignishandler für gerenderte Steuerelemente zu aktivieren. Der Server gibt die HTML-Benutzeroberfläche der Seite so schnell wie möglich als Reaktion auf die anfängliche Anforderung aus, wodurch die Anwendung für Benutzer besser reagiert. Prerendering kann auch die Suchmaschinenoptimierung (SEO) verbessern, indem Inhalte für die erste HTTP-Antwort gerendert werden, die Suchmaschinen zur Berechnung des Seitenrangs verwenden.

Beibehalten des vorab gerenderten Zustands

Ohne Beibehaltung des vorab gerenderten Zustands geht der Zustand verloren, der während des Vorabrenderings verwendet wird, und muss neu erstellt werden, wenn die App vollständig geladen ist. Wenn ein Zustand asynchron erstellt wird, flackert die Benutzeroberfläche möglicherweise, da die vorab gerenderte Benutzeroberfläche ersetzt wird, wenn die Komponente erneut gerendert wird.

Betrachten Sie die folgende PrerenderedCounter1-Zählerkomponente. Die Komponente legt während des Vorabrenderns in die OnInitialized-Lebenszyklusmethode einen anfänglichen zufälligen Zählerwert fest. Nachdem die SignalR-Verbindung mit dem Client hergestellt wurde, wird die Komponente erneut ausgeführt, und der anfängliche Zählerwert wird ersetzt, wenn OnInitialized ein zweites Mal ausgeführt wird.

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

Führen Sie die App aus, und prüfen Sie die Protokollierung aus der Komponente. Es folgt eine Beispielausgabe.

Hinweis

Wenn die App interaktives Routing verwendet und die Seite über eine interne erweiterte Navigation erreicht wird, findet kein Prerendering statt. Daher müssen Sie die gesamte Seite für die PrerenderedCounter1-Komponente neu laden, um die folgende Ausgabe anzuzeigen. Weitere Informationen finden Sie im Abschnitt Interaktives Routing und Prerendering.

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

Die erste protokollierte Anzahl erfolgt während des Vorabrenderings. Die Anzahl wird erneut festgelegt, nachdem die Komponente neu gerendert wurde. Die Benutzeroberfläche flackert auch, wenn die Anzahl von 41 auf 92 aktualisiert wird.

Um den Anfangswert des Zählers während des Vorabrenderings beizubehalten, unterstützt Blazor das Beibehalten des Zustands auf einer vorab gerenderten Seite mithilfe des PersistentComponentState-Diensts (und für Komponenten, die in Seiten oder Ansichten von Razor Pages- oder MVC-Apps eingebettet sind, das Hilfsprogramm für Persist Component State Tag Helper).

Entscheiden Sie, welcher Zustand mithilfe des PersistentComponentState-Diensts beibehalten werden soll, um den vorab gerenderten Zustand beizubehalten. Mit PersistentComponentState.RegisterOnPersisting wird zum Beibehalten des Komponentenzustands ein Rückruf registriert, bevor die App angehalten wird. Der Zustand wird abgerufen, wenn die App fortgesetzt wird.

Das folgende Beispiel veranschaulicht das allgemeine Muster:

  • Der {TYPE}-Platzhalter stellt den Typ der zu speichernden Daten dar.
  • Der {TOKEN}-Platzhalter ist eine Zustandsbezeichnerzeichenfolge. Erwägen Sie die Verwendung von nameof({VARIABLE}), wobei der Platzhalter {VARIABLE} der Name der Variable ist, die den Zustand enthält. Die Verwendung von nameof() für den Zustandsbezeichner verhindert die Verwendung einer Zeichenfolge mit Anführungszeichen.
@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();
    }
}

Im folgenden Beispiel für Zählerkomponenten wird der Zählerzustand während des Vorabrenderns beibehalten und der Zustand abgerufen, um die Komponente zu initialisieren.

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

Wenn die Komponente ausgeführt wird, wird currentCount sie während des Vorabrenderns nur einmal festgelegt. Der Wert wird wiederhergestellt, wenn die Komponente erneut gerendert wird. Es folgt eine Beispielausgabe.

Hinweis

Wenn die App interaktives Routing verwendet und die Seite über eine interne erweiterte Navigation erreicht wird, findet kein Prerendering statt. Daher müssen Sie die gesamte Seite für die PrerenderedCounter2-Komponente neu laden, um die folgende Ausgabe anzuzeigen. Weitere Informationen finden Sie im Abschnitt Interaktives Routing und Prerendering.

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

Durch das Initialisieren von Komponenten mit demselben Zustand, der während des Prerenderings verwendet wird, werden teure Initialisierungsschritte nur einmal ausgeführt. Die gerenderte Benutzeroberfläche entspricht auch der vorab gerenderten Benutzeroberfläche, sodass im Browser kein Flimmern auftritt.

Der beibehaltene vorrenderte Zustand wird an den Client übertragen, in dem er zum Wiederherstellen des Komponentenzustands verwendet wird. Während des clientseitigen Renderings (CSR) InteractiveWebAssemblywerden die Daten für den Browser verfügbar gemacht und dürfen keine vertraulichen, privaten Informationen enthalten. Während des interaktiven serverseitigen Renderings (interaktiver SSR, InteractiveServer), ASP.NET Core Data Protection stellt sicher, dass die Daten sicher übertragen werden. Der InteractiveAuto Rendermodus kombiniert WebAssembly und Server-Interaktivität, daher ist es notwendig, die Datenexposition für den Browser zu berücksichtigen, wie im CSR-Fall.

In Seiten und Ansichten eingebettete Komponenten (Razor Pages/MVC)

Für Komponenten, die in eine Seite oder Ansicht von Razor Pages- oder einer MVC-App eingebettet sind, müssen Sie das Hilfsprogramm Persist Component State Tag Helper mit dem <persist-component-state /> HTML-Tag innerhalb des schließenden </body> Tags des App-Layouts hinzufügen. Dies ist nur für Razor Pages- und MVC-Apps erforderlich. Weitere Informationen finden Sie unter Persist Component State Tag Helper in ASP.NET Core.

Pages/Shared/_Layout.cshtml:

<body>
    ...

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

Interaktives Routing und Vorabrendering

Wenn die Routes Komponente keinen Rendermodus definiert, verwendet die App interaktivität und Navigation pro Seite/Komponente. Durch die Navigation pro Seite/Komponente wird die interne† Navigation mittels verbessertem Routing gehandhabt, nachdem die App interaktiv wird. †Intern bedeutet, dass in diesem Kontext das Ziel der URL des Navigationsereignisses ein Blazor Endpunkt in der App ist.

Der PersistentComponentState-Dienst funktioniert nur beim Laden der ersten Seite und nicht bei internen erweiterten Seitennavigationsereignissen.

Wenn die App eine vollständige (nicht erweiterte) Navigation zu einer Seite ausführt, die den permanenten Komponentenstatus verwendet, wird der permanente Status für die App verfügbar gemacht, wenn sie interaktiv wird.

Wenn bereits eine interaktive Verbindung eingerichtet wurde und eine erweiterte Navigation auf einer Seite ausgeführt wird, die den persistenten Komponentenzustand verwendet, ist der Zustand in der vorhandenen Verbindung nicht verfügbar für die Verwendung durch die Komponente. Es gibt kein Vorabrendern für die interne Seitenanfrage, und der PersistentComponentState-Dienst ist sich nicht bewusst, dass eine erweiterte Navigation stattgefunden hat. Es gibt keinen Mechanismus zum Bereitstellen von Zustandsupdates für Komponenten, die bereits auf einer vorhandenen Schaltung ausgeführt werden. Der Grund dafür ist, dass Blazor nur das Übergeben des Zustands vom Server an den Client unterstützt, wenn die Laufzeit initialisiert wird, nicht nach dem Start der Laufzeit.

Für .NET 10 (November 2025) wird zusätzliche Arbeit am Blazor-Framework zur Lösung dieses Szenarios in Betracht gezogen. Weitere Informationen und Community-Diskussionen zu nicht unterstützten Problemumgehungen, finden Sie unter Unterstützung des persistenten Zustands von Komponenten für erweiterte Seitennavigationen (dotnet/aspnetcore #51584). Nicht unterstützte Workarounds werden von Microsoft nicht für die Verwendung in Blazor-Apps genehmigt. Verwenden Sie Pakete, Ansätze und Code von Drittanbietern auf eigene Gefahr.

Durch das Deaktivieren der erweiterten Navigation wird die Leistung zwar verringert, aber gleichzeitig wird das Problem des Ladezustands mit PersistentComponentState für interne Seitenanforderungen vermieden. Weitere Informationen dazu finden Sie unter ASP.NET Core BlazorRouting und Navigation.

Anleitungen zum Vorabrendering

Anleitungen zum Vorabrendering sind in der Blazor-Dokumentation nach Themen organisiert. Unter den folgenden Links finden Sie alle Anleitungen zum Vorabrendering in der Dokumentation nach Themen geordnet: