Bagikan melalui


Prarender komponen ASP.NET Core Razor

Artikel ini menjelaskan Razor skenario pra-penyajian komponen untuk komponen yang dirender server dalam Blazor Web Apps.

Pra-penyajian adalah proses awalnya merender konten halaman di server tanpa mengaktifkan penanganan aktivitas untuk kontrol yang dirender. Server mengeluarkan UI HTML halaman sesegera mungkin sebagai respons terhadap permintaan awal, yang membuat aplikasi merasa lebih responsif terhadap pengguna. Pra-penyajian juga dapat meningkatkan Pengoptimalan Mesin Pencari (SEO) dengan merender konten untuk respons HTTP awal yang digunakan mesin pencari untuk menghitung peringkat halaman.

Mempertahankan status yang telah dirender sebelumnya

Tanpa mempertahankan status yang telah dirender sebelumnya, status yang digunakan selama pra-penyajian hilang dan harus dibuat ulang saat aplikasi dimuat sepenuhnya. Jika ada status yang dibuat secara asinkron, UI dapat berkedot karena UI yang telah dirender diganti ketika komponen dirender.

Pertimbangkan komponen penghitung berikut PrerenderedCounter1 . Komponen menetapkan nilai penghitung acak awal selama pra-penyajian dalam OnInitialized metode siklus hidup. SignalR Setelah koneksi ke klien dibuat, komponen dirender, dan nilai jumlah awal diganti saat OnInitialized dijalankan untuk kedua kalinya.

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

Jalankan aplikasi dan periksa pengelogan dari komponen. Berikut ini adalah contoh output.

Catatan

Jika aplikasi mengadopsi perutean interaktif (ditingkatkan) dan halaman tercapai melalui navigasi internal, pra-penyajian tidak terjadi. Oleh karena itu, Anda harus melakukan pemuatan ulang halaman penuh agar PrerenderedCounter1 komponen dapat melihat output berikut.

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

Jumlah pertama yang dicatat terjadi selama pra-penyajian. Jumlah diatur lagi setelah prarender saat komponen dirender. Ada juga kedipan di UI ketika hitungan diperbarui dari 41 hingga 92.

Untuk mempertahankan nilai awal penghitung selama pra-penyajian, Blazor mendukung status persisten di halaman yang dirender sebelumnya menggunakan PersistentComponentState layanan (dan untuk komponen yang disematkan ke dalam halaman atau tampilan Razor halaman atau aplikasi MVC, Pembantu Tag Status Komponen Persist).

Untuk mempertahankan status yang telah dirender sebelumnya, putuskan status apa yang akan bertahan menggunakan PersistentComponentState layanan. PersistentComponentState.RegisterOnPersisting mendaftarkan panggilan balik untuk mempertahankan status komponen sebelum aplikasi dijeda. Status diambil saat aplikasi dilanjutkan.

Contoh berikut menunjukkan pola umum:

  • Tempat {TYPE} penampung mewakili jenis data yang akan dipertahankan.
  • Tempat {TOKEN} penampung adalah string pengidentifikasi status. Pertimbangkan untuk menggunakan nameof({VARIABLE}), di mana {VARIABLE} tempat penampung adalah nama variabel yang memegang status. Menggunakan nameof() untuk pengidentifikasi status menghindari penggunaan string yang dikutip.
@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();
    }
}

Contoh komponen penghitung berikut mempertahankan status penghitung selama pra-penyajian dan mengambil status untuk menginisialisasi komponen.

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

Ketika komponen dijalankan, currentCount hanya diatur sekali selama pra-penyajian. Nilai dipulihkan ketika komponen dirender. Berikut ini adalah contoh output.

Catatan

Jika aplikasi mengadopsi perutean interaktif dan halaman tercapai melalui navigasi internal, pra-penyajian tidak terjadi. Oleh karena itu, Anda harus melakukan pemuatan ulang halaman penuh agar PrerenderedCounter2 komponen dapat melihat output berikut.

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

Dengan menginisialisasi komponen dengan status yang sama yang digunakan selama prarender, langkah-langkah inisialisasi mahal hanya dijalankan sekali. UI yang dirender juga cocok dengan UI yang telah dirender sebelumnya, sehingga tidak ada kedipan yang terjadi di browser.

Status pra-penyajian yang dipertahankan ditransfer ke klien, di mana ia digunakan untuk memulihkan status komponen. Selama penyajian sisi klien (CSR, InteractiveWebAssembly), data diekspos ke browser dan tidak boleh berisi informasi privat yang sensitif. Selama penyajian sisi server interaktif (SSR interaktif, InteractiveServer), ASP.NET Perlindungan Data Inti memastikan bahwa data ditransfer dengan aman. Mode InteractiveAuto render menggabungkan interaktivitas WebAssembly dan Server, sehingga perlu untuk mempertimbangkan paparan data ke browser, seperti dalam kasus CSR.

Komponen yang disematkan ke dalam halaman dan tampilan (Razor Pages/MVC)

Untuk komponen yang disematkan ke dalam halaman atau tampilan Razor halaman atau aplikasi MVC, Anda harus menambahkan Pembantu Tag Status Komponen Persist dengan <persist-component-state /> tag HTML di dalam tag penutup </body> tata letak aplikasi. Ini hanya diperlukan untuk Razor aplikasi Pages dan MVC. Untuk informasi selengkapnya, lihat Mempertahankan Pembantu Tag Status Komponen di ASP.NET Core.

Pages/Shared/_Layout.cshtml:

<body>
    ...

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

Perutean dan pra-penyajian interaktif

Navigasi internal untuk perutean interaktif tidak melibatkan permintaan konten halaman baru dari server. Oleh karena itu, pra-penyajian tidak terjadi untuk permintaan halaman internal.

Layanan PersistentComponentState hanya berfungsi pada pemuatan halaman awal dan tidak di seluruh peristiwa navigasi halaman yang disempurnakan. Jika aplikasi melakukan navigasi penuh (tidak ditingkatkan) ke halaman yang menggunakan status komponen persisten, status persisten tersedia untuk digunakan aplikasi saat menjadi interaktif. Tetapi jika sirkuit interaktif telah dibuat dan navigasi yang ditingkatkan dilakukan ke halaman yang merender status komponen yang bertahan, status tersebut tidak tersedia di sirkuit yang ada. Layanan PersistentComponentState ini tidak mengetahui navigasi yang ditingkatkan, dan tidak ada mekanisme untuk mengirimkan pembaruan status ke komponen yang sudah berjalan.

Panduan pra-penyajian

Panduan pra-penyajian diatur dalam Blazor dokumentasi berdasarkan materi pelajaran. Tautan berikut mencakup semua panduan pra-penyajian di seluruh dokumentasi yang ditetapkan oleh subjek: