Bagikan melalui


Rakitan beban malas di ASP.NET Core Blazor WebAssembly

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Peringatan

Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Penting

Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.

Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.

Blazor WebAssembly performa startup aplikasi dapat ditingkatkan dengan menunggu untuk memuat rakitan aplikasi yang dibuat pengembang hingga rakitan diperlukan, yang disebut pemuatan malas.

Bagian awal artikel ini mencakup konfigurasi aplikasi. Untuk demonstrasi yang berfungsi, lihat bagian Contoh lengkap di akhir artikel ini.

Artikel ini hanya berlaku untuk Blazor WebAssembly aplikasi. Pemuatan malas rakitan tidak menguntungkan aplikasi sisi server karena aplikasi yang dirender server tidak mengunduh rakitan ke klien.

Pemuatan malas tidak boleh digunakan untuk rakitan runtime inti, yang mungkin dipangkas saat dipublikasikan dan tidak tersedia pada klien saat aplikasi dimuat.

Tempat penampung ekstensi file ({FILE EXTENSION}) untuk file rakitan

File rakitan menggunakan format pengemasan Webcil untuk rakitan .NET dengan .wasm ekstensi file.

Sepanjang artikel, {FILE EXTENSION} tempat penampung mewakili "wasm".

File assembly didasarkan pada Dynamic-Link Libraries (DLL) dengan .dll ekstensi file.

Sepanjang artikel, {FILE EXTENSION} tempat penampung mewakili "dll".

Konfigurasi file proyek

Tandai rakitan untuk pemuatan malas dalam file proyek aplikasi (.csproj) menggunakan BlazorWebAssemblyLazyLoad item . Gunakan nama rakitan dengan ekstensi file. Blazor Kerangka kerja mencegah perakitan dimuat saat peluncuran aplikasi.

<ItemGroup>
  <BlazorWebAssemblyLazyLoad Include="{ASSEMBLY NAME}.{FILE EXTENSION}" />
</ItemGroup>

Tempat {ASSEMBLY NAME} penampung adalah nama perakitan, dan {FILE EXTENSION} tempat penampung adalah ekstensi file. Ekstensi file diperlukan.

Sertakan satu BlazorWebAssemblyLazyLoad item untuk setiap rakitan. Jika rakitan memiliki dependensi, sertakan BlazorWebAssemblyLazyLoad entri untuk setiap dependensi.

Router konfigurasi komponen

Blazor Kerangka kerja secara otomatis mendaftarkan layanan singleton untuk rakitan pemuatan malas di aplikasi sisi Blazor WebAssembly klien, LazyAssemblyLoader. Metode LazyAssemblyLoader.LoadAssembliesAsync:

  • JS Menggunakan interop untuk mengambil rakitan melalui panggilan jaringan.
  • Memuat rakitan ke dalam runtime yang dijalankan di WebAssembly di browser.

Catatan

Panduan untuk solusi yangBlazor WebAssemblydihosting tercakup dalam rakitan beban Malas di bagian solusi yang dihosting.Blazor WebAssembly

BlazorRouter Komponen menunjuk rakitan yang Blazor mencari komponen yang dapat dirutekan dan juga bertanggung jawab untuk merender komponen untuk rute tempat pengguna menavigasi. Metode Router komponen OnNavigateAsync digunakan bersama dengan pemuatan malas untuk memuat rakitan yang benar untuk titik akhir yang diminta pengguna.

Logika diimplementasikan di dalam OnNavigateAsync untuk menentukan rakitan yang akan dimuat dengan LazyAssemblyLoader. Opsi cara menyusun logika meliputi:

  • Pemeriksaan kondisi di dalam OnNavigateAsync metode .
  • Tabel pencarian yang memetakan rute ke nama rakitan, baik disuntikkan ke komponen atau diimplementasikan dalam @code blok.

Dalam contoh berikut:

  • Namespace untuk Microsoft.AspNetCore.Components.WebAssembly.Services ditentukan.
  • Layanan LazyAssemblyLoader disuntikkan (AssemblyLoader).
  • Tempat {PATH} penampung adalah jalur tempat daftar rakitan harus dimuat. Contoh menggunakan pemeriksaan kondisional untuk satu jalur yang memuat satu set rakitan.
  • Tempat {LIST OF ASSEMBLIES} penampung adalah daftar string nama file rakitan yang dipisahkan koma, termasuk ekstensi file mereka (misalnya, "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}").

App.razor:

@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger

<Router AppAssembly="typeof(App).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject LazyAssemblyLoader AssemblyLoader
@inject ILogger<App> Logger

<Router AppAssembly="typeof(Program).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}

Catatan

Contoh sebelumnya tidak menampilkan konten Router markup komponen Razor (...). Untuk demonstrasi dengan kode lengkap, lihat bagian Contoh lengkap di artikel ini.

Catatan

Dengan rilis ASP.NET Core 5.0.1 dan untuk rilis 5.x tambahan, komponen Router menyertakan parameter PreferExactMatches yang diatur ke @true. Untuk informasi lebih lanjut, lihat Migrasi dari ASP.NET Core 3.1 ke 5.0.

Rakitan yang menyertakan komponen yang dapat dirutekan

Ketika daftar rakitan menyertakan komponen yang dapat dirutekan, daftar rakitan untuk jalur tertentu diteruskan ke Router koleksi komponen AdditionalAssemblies .

Dalam contoh berikut:

  • DaftarAssembly<> dalam lazyLoadedAssemblies meneruskan daftar perakitan ke .AdditionalAssemblies Kerangka kerja mencari rakitan untuk rute dan memperbarui pengumpulan rute jika rute baru ditemukan. Untuk mengakses jenis, Assembly namespace layanan untuk System.Reflection disertakan di bagian App.razor atas file.
  • Tempat {PATH} penampung adalah jalur tempat daftar rakitan harus dimuat. Contoh menggunakan pemeriksaan kondisional untuk satu jalur yang memuat satu set rakitan.
  • Tempat {LIST OF ASSEMBLIES} penampung adalah daftar string nama file rakitan yang dipisahkan koma, termasuk ekstensi file mereka (misalnya, "Assembly1.{FILE EXTENSION}", "Assembly2.{FILE EXTENSION}").

App.razor:

@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(App).Assembly" 
    AdditionalAssemblies="lazyLoadedAssemblies" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private List<Assembly> lazyLoadedAssemblies = new();

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
                   lazyLoadedAssemblies.AddRange(assemblies);
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(Program).Assembly" 
    AdditionalAssemblies="lazyLoadedAssemblies" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private List<Assembly> lazyLoadedAssemblies = new List<Assembly>();

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
           {
               if (args.Path == "{PATH}")
               {
                   var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                       new[] { {LIST OF ASSEMBLIES} });
                   lazyLoadedAssemblies.AddRange(assemblies);
               }
           }
           catch (Exception ex)
           {
               Logger.LogError("Error: {Message}", ex.Message);
           }
    }
}

Catatan

Contoh sebelumnya tidak menampilkan konten Router markup komponen Razor (...). Untuk demonstrasi dengan kode lengkap, lihat bagian Contoh lengkap di artikel ini.

Catatan

Dengan rilis ASP.NET Core 5.0.1 dan untuk rilis 5.x tambahan, komponen Router menyertakan parameter PreferExactMatches yang diatur ke @true. Untuk informasi lebih lanjut, lihat Migrasi dari ASP.NET Core 3.1 ke 5.0.

Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor.

Interaksi pengguna dengan <Navigating> konten

Saat memuat rakitan, yang dapat memakan waktu beberapa detik, Router komponen dapat menunjukkan kepada pengguna bahwa transisi halaman terjadi dengan properti router Navigating .

Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor.

Menangani pembatalan di OnNavigateAsync

Objek NavigationContext yang OnNavigateAsync diteruskan ke panggilan balik berisi CancellationToken yang diatur saat peristiwa navigasi baru terjadi. Panggilan OnNavigateAsync balik harus dilemparkan ketika token pembatalan diatur untuk menghindari terus menjalankan OnNavigateAsync panggilan balik pada navigasi yang ketinggalan jaman.

Untuk informasi selengkapnya, lihat perutean dan navigasi ASP.NET CoreBlazor.

OnNavigateAsync peristiwa dan file rakitan yang diganti namanya

Pemuat sumber daya bergantung pada nama rakitan yang ditentukan dalam blazor.boot.json file. Jika rakitan diganti namanya, nama rakitan yang digunakan dalam OnNavigateAsync panggilan balik dan nama rakitan dalam blazor.boot.json file tidak sinkron.

Untuk memperbaiki hal ini:

  • Periksa untuk melihat apakah aplikasi berjalan di Production lingkungan saat menentukan nama rakitan mana yang akan digunakan.
  • Simpan nama rakitan yang diganti namanya dalam file terpisah dan baca dari file tersebut LazyAssemblyLoader untuk menentukan nama rakitan apa yang akan digunakan dengan layanan dan OnNavigateAsync panggilan balik.

Rakitan beban malas dalam solusi yang dihosting Blazor WebAssembly

Implementasi pemuatan malas kerangka kerja mendukung pemuatan malas dengan pra-penyajian dalam solusi yang dihosting.Blazor WebAssembly Selama pra-penyajian, semua rakitan, termasuk yang ditandai untuk pemuatan malas, diasumsikan dimuat. Daftarkan LazyAssemblyLoader layanan secara manual dalam Server proyek.

Di bagian Program.cs atas file Server proyek, tambahkan namespace layanan untuk Microsoft.AspNetCore.Components.WebAssembly.Services:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Server Dalam Program.cs proyek, daftarkan layanan:

builder.Services.AddScoped<LazyAssemblyLoader>();

Di bagian Startup.cs atas file Server proyek, tambahkan namespace layanan untuk Microsoft.AspNetCore.Components.WebAssembly.Services:

using Microsoft.AspNetCore.Components.WebAssembly.Services;

Dalam Startup.ConfigureServices (Startup.cs) Server proyek, daftarkan layanan:

services.AddScoped<LazyAssemblyLoader>();

Contoh lengkap

Demonstrasi di bagian ini:

  • Membuat rakitan kontrol robot (GrantImaharaRobotControls.{FILE EXTENSION}) sebagaiRazor pustaka kelas (RCL) yang menyertakan Robot komponen (Robot.razor dengan templat /robotrute ).
  • Lazily memuat rakitan RCL untuk merender komponennya Robot saat /robot URL diminta oleh pengguna.

Buat aplikasi mandiri Blazor WebAssembly untuk menunjukkan pemuatan Razor malas rakitan pustaka kelas. Beri nama proyek LazyLoadTest.

Tambahkan proyek pustaka kelas ASP.NET Core ke solusi:

  • Visual Studio: Klik kanan file solusi di Penjelajah Solusi dan pilih Tambahkan>Proyek baru. Dari dialog jenis proyek baru, pilih Razor Pustaka Kelas. Beri nama proyek GrantImaharaRobotControls. Jangan pilih halaman Dukungan dan kotak centang tampilan.
  • Visual Studio Code/.NET CLI: Jalankan dotnet new razorclasslib -o GrantImaharaRobotControls dari prompt perintah. Opsi -o|--output membuat folder dan menamai proyek GrantImaharaRobotControls.

Komponen contoh yang disajikan nanti di bagian ini menggunakan Blazor formulir. Dalam proyek RCL, tambahkan Microsoft.AspNetCore.Components.Forms paket ke proyek.

Catatan

Untuk panduan tentang menambahkan paket ke aplikasi .NET, lihat artikel di bagian Menginstal dan mengelola paket di Alur kerja konsumsi paket (dokumentasi NuGet). Konfirmasikan versi paket yang benar di NuGet.org.

Buat HandGesture kelas di RCL dengan ThumbUp metode yang secara hipotetis membuat robot melakukan gerakan jempol. Metode menerima argumen untuk sumbu, Left atau Right, sebagai enum. Metode ini kembali pada keberhasilan true .

HandGesture.cs:

using Microsoft.Extensions.Logging;

namespace GrantImaharaRobotControls;

public static class HandGesture
{
    public static bool ThumbUp(Axis axis, ILogger logger)
    {
        logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis);

        // Code to make robot perform gesture

        return true;
    }
}

public enum Axis { Left, Right }
using Microsoft.Extensions.Logging;

namespace GrantImaharaRobotControls
{
    public static class HandGesture
    {
        public static bool ThumbUp(Axis axis, ILogger logger)
        {
            logger.LogInformation("Thumb up gesture. Axis: {Axis}", axis);

            // Code to make robot perform gesture

            return true;
        }
    }

    public enum Axis { Left, Right }
}

Tambahkan komponen berikut ke akar proyek RCL. Komponen mengizinkan pengguna untuk mengirimkan permintaan gerakan jempol kiri atau kanan.

Robot.razor:

@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm FormName="RobotForm" Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in Enum.GetValues<Axis>())
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new() { AxisSelection = Axis.Left };
    private string? message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}
@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in Enum.GetValues<Axis>())
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new() { AxisSelection = Axis.Left };
    private string? message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}
@page "/robot"
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.Extensions.Logging
@inject ILogger<Robot> Logger

<h1>Robot</h1>

<EditForm Model="robotModel" OnValidSubmit="HandleValidSubmit">
    <InputRadioGroup @bind-Value="robotModel.AxisSelection">
        @foreach (var entry in (Axis[])Enum
            .GetValues(typeof(Axis)))
        {
            <InputRadio Value="entry" />
            <text>&nbsp;</text>@entry<br>
        }
    </InputRadioGroup>

    <button type="submit">Submit</button>
</EditForm>

<p>
    @message
</p>

@code {
    private RobotModel robotModel = new RobotModel() { AxisSelection = Axis.Left };
    private string message;

    private void HandleValidSubmit()
    {
        Logger.LogInformation("HandleValidSubmit called");

        var result = HandGesture.ThumbUp(robotModel.AxisSelection, Logger);

        message = $"ThumbUp returned {result} at {DateTime.Now}.";
    }

    public class RobotModel
    {
        public Axis AxisSelection { get; set; }
    }
}

LazyLoadTest Dalam proyek, buat referensi proyek untuk GrantImaharaRobotControls RCL:

  • Visual Studio: Klik kanan LazyLoadTest proyek dan pilih Tambahkan>Referensi Proyek untuk menambahkan referensi proyek untuk GrantImaharaRobotControls RCL.
  • Visual Studio Code/.NET CLI: Jalankan dotnet add reference {PATH} dalam shell perintah dari folder proyek. Tempat {PATH} penampung adalah jalur ke proyek RCL.

Tentukan rakitan RCL untuk pemuatan malas dalam LazyLoadTest file proyek aplikasi (.csproj):

<ItemGroup>
    <BlazorWebAssemblyLazyLoad Include="GrantImaharaRobotControls.{FILE EXTENSION}" />
</ItemGroup>

Komponen berikut Router menunjukkan pemuatan GrantImaharaRobotControls.{FILE EXTENSION} rakitan saat pengguna menavigasi ke /robot. Ganti komponen default App aplikasi dengan komponen berikut App .

Selama transisi halaman, pesan bergaya ditampilkan kepada pengguna dengan <Navigating> elemen . Untuk informasi selengkapnya, lihat bagian Interaksi pengguna dengan <Navigating> konten .

Rakitan ditetapkan ke AdditionalAssemblies, yang menghasilkan router mencari perakitan untuk komponen yang dapat dirutekan, di mana ia menemukan Robot komponen. Rute Robot komponen ditambahkan ke koleksi rute aplikasi. Untuk informasi selengkapnya, lihat artikel perutean dan navigasi ASP.NET Core Blazor dan Rakitan yang menyertakan komponen yang dapat dirutekan di artikel ini.

App.razor:

@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(App).Assembly"
        AdditionalAssemblies="lazyLoadedAssemblies" 
        OnNavigateAsync="OnNavigateAsync">
    <Navigating>
        <div style="padding:20px;background-color:blue;color:white">
            <p>Loading the requested page&hellip;</p>
        </div>
    </Navigating>
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

@code {
    private List<Assembly> lazyLoadedAssemblies = new();

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if (args.Path == "robot")
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
                lazyLoadedAssemblies.AddRange(assemblies);
            }
        }
        catch (Exception ex)
        {
            Logger.LogError("Error: {Message}", ex.Message);
        }
    }
}
@using System.Reflection
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.WebAssembly.Services
@using Microsoft.Extensions.Logging
@inject ILogger<App> Logger
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="typeof(Program).Assembly"
        AdditionalAssemblies="lazyLoadedAssemblies" 
        OnNavigateAsync="OnNavigateAsync">
    <Navigating>
        <div style="padding:20px;background-color:blue;color:white">
            <p>Loading the requested page&hellip;</p>
        </div>
    </Navigating>
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

@code {
    private List<Assembly> lazyLoadedAssemblies = new List<Assembly>();

    private async Task OnNavigateAsync(NavigationContext args)
    {
        try
        {
            if (args.Path == "robot")
            {
                var assemblies = await AssemblyLoader.LoadAssembliesAsync(
                    new[] { "GrantImaharaRobotControls.{FILE EXTENSION}" });
                lazyLoadedAssemblies.AddRange(assemblies);
            }
        }
        catch (Exception ex)
        {
            Logger.LogError("Error: {Message}", ex.Message);
        }
    }
}

Buat dan jalankan aplikasi.

Robot Ketika komponen dari RCL diminta di /robot, GrantImaharaRobotControls.{FILE EXTENSION} rakitan dimuat dan Robot komponen dirender. Anda dapat memeriksa pemuatan rakitan di tab Jaringan alat pengembang browser.

Pecahkan masalah

  • Jika penyajian tak terduga terjadi, seperti merender komponen dari navigasi sebelumnya, konfirmasikan bahwa kode melempar jika token pembatalan diatur.
  • Jika rakitan dikonfigurasi untuk pemuatan malas yang tiba-tiba dimuat saat aplikasi dimulai, periksa apakah rakitan ditandai untuk pemuatan malas dalam file proyek.

Catatan

Masalah yang diketahui ada untuk memuat jenis dari rakitan yang dimuat dengan malas. Untuk informasi selengkapnya, lihat Blazor WebAssembly lazy loading assemblies not working when using @ref attribute in the component (dotnet/aspnetcore #29342) .

Sumber Daya Tambahan: