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

Microsoft.FluentUI页面刷新时出现渲染闪烁,如何消除该问题?

问题:Microsoft.FluentUI Blazor 页面刷新时出现无样式闪烁

使用 Microsoft.FluentUI.AspNetCore.Components 开发 Blazor 应用时,刷新页面(F5)会出现明显的无样式闪烁:页面初始渲染时完全未应用任何组件样式,数毫秒后样式才加载生效。该问题可通过官方模板100%复现,操作步骤如下:

dotnet new install Microsoft.FluentUI.AspNetCore.Templates
dotnet new fluentblazor --name MyFluentApp
cd MyFluentApp
dotnet run

启动后访问 /weather 页面,刷新时闪烁现象尤为突出。

解决方案

以下是几种可彻底消除或缓解该闪烁问题的实操方法:

1. 同步加载核心样式文件

将 FluentUI 的核心样式从异步加载改为同步加载,确保样式在页面渲染前完成加载:

  • 对于 Blazor Server:修改 _Host.cshtml 的 <head> 区域,替换原有的样式引用:
<!-- 删除原异步加载的 link 标签,替换为同步加载 -->
<link href="_content/Microsoft.FluentUI.AspNetCore.Components/css/fluentui.min.css" rel="stylesheet" />
  • 对于 Blazor WebAssembly:修改 wwwroot/index.html 做同样操作。

2. 启用服务器端预渲染(Blazor Server 专属)

通过服务器端预渲染提前生成带完整样式的页面HTML,客户端拿到的就是已渲染好的页面,避免初始无样式状态:

  • 在 Program.cs 中配置交互式服务器组件:
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();
  • 在 _Host.cshtml 中设置组件的渲染模式为预渲染:
<component type="typeof(App)" render-mode="ServerPrerendered" />

3. 添加预加载指令提升样式加载优先级

使用 preload 指令告诉浏览器优先加载 FluentUI 样式文件,缩短样式加载时间:

<!-- 放在页面 <head> 的最上方 -->
<link rel="preload" href="_content/Microsoft.FluentUI.AspNetCore.Components/css/fluentui.min.css" as="style">
<link href="_content/Microsoft.FluentUI.AspNetCore.Components/css/fluentui.min.css" rel="stylesheet">

4. 用骨架屏掩盖加载过程

如果上述方法仍有轻微闪烁,可添加骨架屏在样式加载完成前占位,降低用户感知:

  • 在 App.razor 中添加条件渲染逻辑:
@inject IJSRuntime JSRuntime

@if (!_stylesLoaded)
{
    <div class="skeleton-wrapper">
        <!-- 模拟页面布局的骨架屏,可根据实际页面调整 -->
        <div class="skeleton-header h-16 bg-gray-200 rounded"></div>
        <div class="skeleton-content mt-4 space-y-4">
            <div class="h-4 bg-gray-200 rounded w-3/4"></div>
            <div class="h-4 bg-gray-200 rounded w-full"></div>
            <div class="h-4 bg-gray-200 rounded w-5/6"></div>
        </div>
    </div>
}
else
{
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
}

@code {
    private bool _stylesLoaded;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("waitForFluentStyles");
            _stylesLoaded = true;
            StateHasChanged();
        }
    }
}
  • 在 wwwroot/js/site.js 中添加等待样式加载的脚本:
async function waitForFluentStyles() {
    const styleLink = document.querySelector('link[href*="fluentui.min.css"]');
    if (styleLink) {
        await new Promise(resolve => {
            if (styleLink.loaded) resolve();
            styleLink.onload = resolve;
        });
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:07:50