Blazor WASM中路由切换后Rive动画卡顿问题求助
问题:Blazor WASM中反复切换页面后Rive动画卡顿、内存泄漏
我基于Blazor WASM基础模板开发,在首页("/")展示Rive动画。反复切换到Counter页("/counter")再返回首页约20次后,动画出现严重卡顿;切换27次后,甚至需要20秒才能渲染动画。同时CPU占用上升12%,内存占用增加120MB。通过开发者工具排查发现内存占用主要来自Rive库,我已尝试实现Dispose逻辑(代码如下),想确认是代码实现有误,还是需要向Rive仓库或ASP.NET提交新issue?
相关代码
Index.razor
@page "/" @inject IJSRuntime JSRuntime @implements IAsyncDisposable <canvas id="canvas" width="500" height="500"></canvas> @code { IJSObjectReference? rivWrapper; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { rivWrapper = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./Pages/Index.razor.js"); await rivWrapper.InvokeVoidAsync("createRive"); } } public async ValueTask DisposeAsync() { await rivWrapper!.DisposeAsync(); } }
Index.razor.js
export function createRive() { const r = new rive.Rive({ src: 'bear.riv', canvas: document.getElementById('canvas'), autoplay: true, }); }
index.html代码片段
<script src="https://unpkg.com/@rive-app/canvas@1.0.97"></script>
问题分析与结论
你的代码存在资源未正确清理的问题,并非框架或库的原生bug:
- Rive实例未销毁:当前代码只Dispose了JS模块引用,但每次创建的
rive.Rive实例没有被销毁。Rive动画会持续占用CPU和内存资源,即使组件已被卸载,这些实例仍在后台运行,导致内存泄漏。 - 模块引用Dispose的局限性:
IJSObjectReference.DisposeAsync()仅清理Blazor与JS模块的绑定关系,不会自动销毁JS内部创建的Rive实例。
修复方案
修改JS代码,保存Rive实例引用,并添加销毁方法;在Blazor组件的Dispose逻辑中调用该方法:
修改后的Index.razor.js
let riveInstance = null; export function createRive() { riveInstance = new rive.Rive({ src: 'bear.riv', canvas: document.getElementById('canvas'), autoplay: true, }); } export function destroyRive() { if (riveInstance) { riveInstance.stop(); // 停止动画 riveInstance.dispose(); // 销毁实例释放资源 riveInstance = null; } }
修改后的Index.razor的Dispose逻辑
public async ValueTask DisposeAsync() { if (rivWrapper != null) { await rivWrapper.InvokeVoidAsync("destroyRive"); await rivWrapper.DisposeAsync(); } }
验证建议
修复后反复切换页面,通过浏览器开发者工具的内存面板查看内存占用变化:如果切换后内存能稳定回落,说明泄漏问题已解决。若问题仍存在,再考虑向Rive仓库提交issue(需附带复现步骤和内存快照)。
内容的提问来源于stack exchange,提问作者Laftek
相关产品推荐
相关产品推荐

