.NET 9 Blazor交互式服务器:官方异步渲染方案失效问询
Blazor交互式服务器(.NET 9)异步调用重复执行的问题与改进建议
问题背景
在Blazor交互式服务器(.NET 9)开发中,将最长耗时10秒的遗留服务调用放在OnInitializedAsync方法内时,发现该调用会执行两次,导致页面加载缓慢且效率低下。这种双重渲染行为在.NET官方文档中已有说明,文档末尾提供了「处理渲染时未完成的异步操作」的解决方案。
官方方案尝试与失效原因
尝试了官方推荐的方案:添加[StreamRendering]特性、将数据存储为JSON对象、实现IDisposable接口,但始终无法匹配数据的键。推测原因是加载的是对象列表而非示例中的基本类型(社区相关帖子也支持这一推测)。通过另一个仅返回字符串的组件验证,确认不是实现或项目配置问题,官方方案对复杂对象列表场景无效。
当前临时解决方案(Workaround)
因官方方案无效,采用了以下临时实现:
protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) { data = await LongDataCall(); InvokeAsync(StateHasChanged); IsLoading = false; } }
该方法能解决重复调用问题,但并非设计用于此类场景,且存在竞态条件风险。
替代方案限制
已知缓存等后端方案可解决重复调用问题,但在无法使用缓存的场景下,官方方案又不适用于复杂对象列表的情况。
改进建议
既然OnInitializedAsync会被调用两次,且是放置长耗时服务调用的推荐位置,建议为其添加类似OnAfterRenderAsync中的isPrerender参数,这样可以实现:
- 若预渲染与SignalR连接间隔可忽略,选择不在预渲染中执行无效的数据调用
- 仅在预渲染阶段启动数据调用,并在交互式渲染中复用任务/数据
- 提升性能,避免多数组件因轻微性能问题陷入复杂处理流程
从技术角度看,服务器明确知晓当前是否处于预渲染阶段,添加该参数具备可行性。
内容的提问来源于stack exchange,提问作者Zachary Quinn
相关产品推荐
相关产品推荐

