Składniki prerender ASP.NET Core Razor

W tym artykule opisano Razor scenariusze prerendering składników dla składników renderowanych przez serwer w usłudze Blazor Web Apps.

Prerendering to proces początkowego renderowania zawartości strony na serwerze bez włączania procedur obsługi zdarzeń dla renderowanych kontrolek. Serwer zwraca interfejs użytkownika HTML strony tak szybko, jak to możliwe w odpowiedzi na początkowe żądanie, co sprawia, że aplikacja czuje się bardziej elastyczna dla użytkowników. Prerendering może również poprawić optymalizację aparatu wyszukiwania (SEO) przez renderowanie zawartości początkowej odpowiedzi HTTP używanej przez wyszukiwarki do obliczania rangi strony.

Utrwalanie stanu wstępnego

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ż wstępnie utworzony interfejs użytkownika jest zastępowany, gdy składnik jest rerendered.

Rozważ następujący PrerenderedCounter1 składnik licznika. Składnik ustawia początkową losową wartość licznika podczas prerenderingu w OnInitialized metodzie cyklu życia. Po nawiązaniu SignalR połączenia z klientem element rerenders składnika i początkowa wartość licznika jest zastępowana podczas OnInitialized wykonywania po raz drugi.

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

Uruchom aplikację i sprawdź rejestrowanie ze składnika. Poniżej przedstawiono przykładowe dane wyjściowe.

Uwaga

Jeśli aplikacja przyjmuje routing interakcyjny (rozszerzony), a strona zostanie osiągnięta za pośrednictwem nawigacji wewnętrznej, wstępne przetwarzanie nie nastąpi. W związku z tym należy wykonać ponowne ładowanie pełnej strony dla PrerenderedCounter1 składnika, aby wyświetlić następujące dane wyjściowe.

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

Pierwsza zarejestrowana liczba występuje podczas prerenderingu. Liczba jest ponownie ustawiana po wstępnieenderingu, gdy składnik jest rerendered. W interfejsie użytkownika występuje również migotanie, gdy liczba aktualizacji z zakresu od 41 do 92.

Aby zachować początkową wartość licznika podczas prerenderingu, Blazor obsługuje utrwalanie stanu na stronie prerendered przy użyciu PersistentComponentState usługi (oraz składników osadzonych na stronach lub widokach Razor stron lub aplikacji MVC, Pomocnik utrwalania tagu stanu składnika).

Aby zachować stan wstępnego, zdecyduj, jaki stan ma być trwały przy użyciu PersistentComponentState usługi. PersistentComponentState.RegisterOnPersisting rejestruje wywołanie zwrotne, aby utrwało stan składnika przed wstrzymaniem aplikacji. Stan jest pobierany po wznowieniu działania aplikacji.

W poniższym przykładzie przedstawiono ogólny wzorzec:

  • Symbol {TYPE} zastępczy reprezentuje typ danych do utrwalania.
  • Symbol {TOKEN} zastępczy jest ciągiem identyfikatora stanu. Rozważ użycie elementu nameof({VARIABLE}), gdzie {VARIABLE} symbol zastępczy jest nazwą zmiennej, która przechowuje stan. Użycie nameof() dla identyfikatora stanu pozwala uniknąć użycia cytowanego ciągu.
@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();
    }
}

Poniższy przykład składnika licznika utrwala stan licznika podczas wstępnegoenderowania i pobiera stan w celu zainicjowania składnika.

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

Gdy składnik jest wykonywany, currentCount jest ustawiany tylko raz podczas prerenderingu. Wartość jest przywracana, gdy składnik jest rerendered. Poniżej przedstawiono przykładowe dane wyjściowe.

Uwaga

Jeśli aplikacja przyjmuje routing interakcyjny, a strona zostanie osiągnięta za pośrednictwem nawigacji wewnętrznej, wstępne przetwarzanie nie nastąpi. W związku z tym należy wykonać ponowne ładowanie pełnej strony dla PrerenderedCounter2 składnika, aby wyświetlić następujące dane wyjściowe.

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

Inicjując składniki o tym samym stanie używanym podczas prerenderingu, wszystkie kosztowne kroki inicjowania są wykonywane tylko raz. Renderowany interfejs użytkownika jest również zgodny ze wstępnie zdefiniowanym interfejsem użytkownika, więc w przeglądarce nie występuje migotanie.

Składniki osadzone na stronach i widokach (Razor Pages/MVC)

W przypadku składników osadzonych na stronie lub widoku Razor aplikacji Pages lub MVC należy dodać Pomocnik tagu stanu składnika utrwalania z <persist-component-state /> tagiem HTML wewnątrz tagu zamykającego </body> układu aplikacji. Jest to wymagane tylko w przypadku Razor aplikacji Pages i MVC. Aby uzyskać więcej informacji, zobacz Utrwalanie pomocnika tagu stanu składnika w ASP.NET Core.

Pages/Shared/_Layout.cshtml:

<body>
    ...

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

Routing interakcyjny i wstępne tworzenie

Nawigacja wewnętrzna na potrzeby routingu interakcyjnego nie obejmuje żądania nowej zawartości strony z serwera. W związku z tym wstępne przetwarzanie nie występuje w przypadku żądań stron wewnętrznych.

Usługa PersistentComponentState działa tylko na początkowym ładowaniu strony, a nie na rozszerzonych zdarzeniach nawigacji stron. Jeśli aplikacja wykonuje pełną (nie rozszerzoną) nawigację do strony korzystającej ze stanu trwałego składnika, stan utrwalonego jest udostępniany aplikacji do użycia, gdy stanie się interakcyjny. Jeśli jednak obwód interakcyjny został już ustanowiony, a ulepszona nawigacja jest wykonywana na stronie, która renderuje stan utrwalonego składnika, stan ten nie jest udostępniany w istniejącym obwodzie. Usługa PersistentComponentState nie zna rozszerzonej nawigacji i nie ma mechanizmu dostarczania aktualizacji stanu do składników, które są już uruchomione.

Wskazówki dotyczące prerenderingu

Wskazówki dotyczące prerenderingu są zorganizowane w dokumentacji według tematu Blazor . Poniższe linki obejmują wszystkie wskazówki dotyczące prerenderingu w całej dokumentacji ustawionej według tematu: