Blazor中父组件与子组件调用StateHasChanged的性能差异对比
Blazor两种StateHasChanged调用方案的性能差异解答
两种实现存在明确的性能差异,你的实测结果完全符合Blazor的默认渲染机制:
父组件调用StateHasChanged的渲染逻辑
StateHasChanged的触发范围是当前组件+其下挂载的所有子组件。默认情况下,不管子组件的参数有没有发生变化,父组件重渲染时所有子组件都会执行渲染树对比逻辑,也就会触发OnAfterRender等生命周期方法。如果父组件下挂载了大量子组件,会产生很多不必要的性能开销。- 只有当子组件显式实现了
ShouldRender返回false、或者使用了不可变类型参数等优化手段时,才会跳过无意义的渲染计算。
子组件内部调用StateHasChanged的渲染逻辑
- 此时
StateHasChanged仅作用于当前子组件本身,只会触发当前子组件(以及它的子组件,若有)的渲染流程,父组件和其他无关子组件完全不会参与重渲染,性能开销远低于父组件调用的方案。 - 这种实现同时也符合关注点分离的设计原则:收藏列表的展示逻辑本身只和这个子组件相关,把事件订阅、数据修改、渲染触发的逻辑全部收敛到子组件内部,既降低了父子组件的耦合度,也方便后续维护。
注意事项
你需要额外补充事件取消订阅的逻辑,避免内存泄漏:
@implements IDisposable [Inject] private IProjectActionsService ProjectActionsService { get; set; } [Parameter] public ProjectModel Project { get; set; } protected override void OnInitialized() { ProjectActionsService.FavouritesOnChange += FavouriteTasksChanged; } private void FavouriteTasksChanged(TreeItemModel treeItem) { // 原有业务逻辑 } public void Dispose() { ProjectActionsService.FavouritesOnChange -= FavouriteTasksChanged; }
另外要注意:你修改的是共享的ProjectModel引用类型参数,如果其他组件也依赖Project.TreeDataSource的内容,那些组件如果没有监听对应的变更通知的话,不会自动触发重渲染,需要你根据业务场景判断是否符合预期。
内容的提问来源于stack exchange,提问作者MarchalPT
相关产品推荐
相关产品推荐

