问题描述
在Blazor中,有几种执行JavaScript代码的选项:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
IJSObjectReference module = await JSRuntime.InvokeAsync<IJSObjectReference>("import",".script1.js");
await module.InvokeVoidAsync("sampleFunction1");
}
}
index.html:
<script src="script1.js"></script>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("sampleFunction1");
}
}
两种方法都行得通,但是从性能,代码维护和代码清洁度的角度来看,哪一种方法更可取?
解决方法
我会使用第一个(在 OnAfterRenderAsync 期间导入),这是我的解释:
-
如果您将 js 编写为特定组件的扩展,您将获得一个可重用、可分解和可维护的 js 模块,这些模块在未来可以轻松被单元测试覆盖/重构。
-
未使用但加载到浏览器中的 js 内容的百分比会更小且更高效。最终用户不应该为了“以防万一”而收到一堆 js。可悲的是,blazor 本身并没有使用这种前端优化,并且会加载大量“以防万一”代码。 coverage for several js modules in comparison to blazor.server.js
-
无需在渲染中放置 javascript 链接。它带来了一些好处:
- 预渲染的 html 不会被关键渲染路径阻止程序 (https://developers.google.com/web/fundamentals/performance/critical-rendering-path/adding-interactivity-with-javascript) 污染
- 在将其标记为异步以修复渲染阻塞后,无需等待它加载以调用某些方法:)
- 为最终用户减少网络开销
- 开箱即用地集成到由 blazor ( https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-3.1&tabs=visual-studio ) 生成的 PWA service-worker.js