Blazor Server端页面重复加载及闪烁问题排查与解决
Blazor Server页面自动重载、两次加载及闪烁问题排查与解决
问题现象
所有应用页面打开后会自动重载,出现两次加载的情况并伴随页面闪烁。
相关代码与截图
Dashboard页面代码
protected override async Task OnInitializedAsync() { await getcountServers(); await getcountDatabases(); await RefreshDropDownListFilter(); await RefreshDropDownListOwnerFilter(); await RefreshDropDownListDatabaseFilter(); await SearchFilter(); await GetFirstCharachter(); } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { } }
_Host文件代码
@page "/" <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>UC.AppRepository.UI</title> <base href="~/" /> <link rel="stylesheet" href="_content/Radzen.Blazor/css/default-base.css"> <link rel="stylesheet" href="_content/Radzen.Blazor/css/default.css"> <link rel="stylesheet" href="~/assets/lib/bootstrap/dist/css/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="BlazorUI.styles.css" rel="stylesheet" /> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css"> <script src="~/js/jquery-3.6.3.js"></script> </head> <body> <component type="typeof(App)" render-mode="ServerPrerendered" /> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script> <script src="_framework/blazor.server.js"></script> <script src="_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.js"></script> <script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/select2@4.0.12/dist/js/select2.min.js"></script> <script src="~/assets/js/downloadexcel.js"></script> <script src="~/js/downloadexcel.js"></script> <script src="~/assets/js/checksessiontimeout.js"></script> </body> </html>
浏览器开发者工具网络请求截图

问题原因
ServerPrerendered渲染模式特性
当前_Host.cshtml使用render-mode="ServerPrerendered",这是Blazor Server默认模式。该模式会先在服务器预渲染静态HTML发送到浏览器,再建立SignalR连接进行交互式渲染,直接导致页面两次加载并闪烁。重复资源引用
_Host.cshtml中重复引入了jQuery(本地+CDN两个版本)、Bootstrap(本地+Bootstrap5+Bootstrap4多版本)、downloadexcel.js(两次引用),重复资源加载会触发额外请求,加重页面闪烁。初始化逻辑重复执行
OnInitializedAsync中的异步方法会在预渲染和交互式渲染两个阶段都执行,导致后端接口被调用两次(从网络截图可见重复API请求),加剧页面加载波动。
解决方案
1. 调整渲染模式(按需选择)
如果不需要预渲染优化SEO,直接将渲染模式改为Server,避免两次渲染:
<component type="typeof(App)" render-mode="Server" />
若需保留预渲染,需处理初始化逻辑重复执行问题。
2. 避免初始化逻辑重复执行
通过判断是否为浏览器环境(交互式渲染阶段),跳过预渲染时的接口调用:
protected override async Task OnInitializedAsync() { // 仅在交互式渲染阶段执行 if (OperatingSystem.IsBrowser()) { await getcountServers(); await getcountDatabases(); await RefreshDropDownListFilter(); await RefreshDropDownListOwnerFilter(); await RefreshDropDownListDatabaseFilter(); await SearchFilter(); await GetFirstCharachter(); } }
或把逻辑移至OnAfterRenderAsync,利用firstRender标记确保仅执行一次:
protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await getcountServers(); await getcountDatabases(); await RefreshDropDownListFilter(); await RefreshDropDownListOwnerFilter(); await RefreshDropDownListDatabaseFilter(); await SearchFilter(); await GetFirstCharachter(); StateHasChanged(); } }
3. 清理重复资源引用
删除重复的脚本和样式,统一版本,示例如下:
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>UC.AppRepository.UI</title> <base href="~/" /> <link rel="stylesheet" href="_content/Radzen.Blazor/css/default-base.css"> <link rel="stylesheet" href="_content/Radzen.Blazor/css/default.css"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css"> <link href="css/site.css" rel="stylesheet" /> <link href="BlazorUI.styles.css" rel="stylesheet" /> <script src="~/js/jquery-3.6.3.js"></script> </head> <body> <component type="typeof(App)" render-mode="ServerPrerendered" /> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script> <script src="_framework/blazor.server.js"></script> <script src="_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.js"></script> <script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script> <script src="https://cdn.jsdelivr.net/npm/select2@4.0.12/dist/js/select2.min.js"></script> <script src="~/assets/js/downloadexcel.js"></script> <script src="~/assets/js/checksessiontimeout.js"></script> </body> </html>
内容的提问来源于stack exchange,提问作者ahmed abdelaziz
相关产品推荐
相关产品推荐

