You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何缩短ASP.NET Core 7托管Blazor WebAssembly初始加载时间?

ASP.NET Core 7托管式Blazor WebAssembly首屏加载优化方案(已排除预渲染)

问题描述

我用ASP.NET Core 7开发了一个托管式Blazor WebAssembly网站,客户端项目实现了自定义AuthenticationStateProvider,整体包含服务端、共享、基础设施、数据等多个项目。现在遇到的问题是网站启动时首屏加载耗时过长。

客户端Program.cs代码如下:

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddBlazoredSessionStorage();

builder.Services.AddBlazoredToast();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();

await builder.Build().RunAsync();

我尝试过预渲染,但这会破坏现有架构。另外项目中有大量页面,想了解是否有路由懒加载机制可以优化,目前没找到有效方案,请问还有哪些方法能加快初始加载速度?


优化方案

1. 实现路由懒加载(模块拆分)

Blazor WASM支持将非首屏页面拆分为独立的Razor类库(RCL),通过懒加载仅在用户访问对应路由时加载目标程序集,直接减少初始包体积。

具体实现步骤:

  • 将非核心页面/组件拆分到单独的RCL项目中,每个RCL对应一个业务模块
  • 在主项目的App.razor中通过LazyAssemblyLoader实现路由级懒加载:
@inject LazyAssemblyLoader AssemblyLoader

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        @if (routeData.PageType.FullName.StartsWith("YourProject.Features.Order"))
        {
            @await LoadAndRenderModule(routeData, "YourProject.Features.Order.dll")
        }
        else if (routeData.PageType.FullName.StartsWith("YourProject.Features.User"))
        {
            @await LoadAndRenderModule(routeData, "YourProject.Features.User.dll")
        }
        else
        {
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        }
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>抱歉,该地址不存在</p>
        </LayoutView>
    </NotFound>
</Router>

@code {
    private async Task<IComponent> LoadAndRenderModule(RouteData routeData, string assemblyName)
    {
        var assemblies = await AssemblyLoader.LoadAssembliesAsync(new[] { assemblyName });
        var targetPage = assemblies.SelectMany(a => a.ExportedTypes)
            .First(t => t == routeData.PageType);
        return Activator.CreateInstance(targetPage) as IComponent;
    }
}
  • 拆分后的RCL需设置CopyLocalLockFileAssemblies = false,避免依赖重复打包到主程序集

2. 启用AOT编译

在客户端项目的.csproj中开启AOT编译,将IL代码提前编译为机器码,既减少运行时JIT开销,也能显著缩小包体积:

<PropertyGroup>
    <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

注意:AOT会增加构建时间,且对反射等动态特性有兼容性限制,需提前做兼容性测试。

3. 依赖裁剪与压缩

  • 启用响应压缩:在服务端Program.cs中添加静态文件压缩中间件,降低传输体积:
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
// 启用响应压缩
app.UseResponseCompression();
  • 裁剪冗余依赖:检查客户端及共享项目的NuGet包,移除未使用的依赖;对于共享项目,仅引用必要的组件,避免依赖链膨胀。
  • 启用代码修剪:在客户端.csproj中开启链接器,移除未使用的代码:
<PropertyGroup>
    <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking>
</PropertyGroup>

4. 优化AuthenticationStateProvider逻辑

自定义认证状态提供者的初始化逻辑可能阻塞首屏渲染,可做如下调整:

  • 避免在构造函数中执行耗时的异步认证查询,改为首次访问认证状态时异步加载
  • 首屏组件避免同步等待认证状态,改用CascadingAuthenticationState配合异步渲染,比如显示加载占位符直到认证状态就绪

5. 静态资源缓存优化

  • 配置服务端静态文件的长期缓存策略,在Program.cs中设置:
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append(
            "Cache-Control", "public, max-age=31536000, immutable");
    }
});
  • 将CSS、图片、第三方JS等静态资源部署到CDN,降低用户请求延迟

6. 简化首屏组件

  • 首屏仅保留核心UI元素,将侧边栏菜单、非核心统计组件等改为延迟加载
  • 避免在首屏组件中初始化大量数据或执行复杂计算,改用异步加载并显示加载状态

内容的提问来源于stack exchange,提问作者Robin Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:00:26