Blazor 性能

Posted

技术标签:

【中文标题】Blazor 性能【英文标题】:Blazor performance 【发布时间】:2018-10-29 13:10:27 【问题描述】:

我想开始使用 Blazor,尽管它仍处于 alpha 级别。

据我了解,Blazor 使用 WebAssembly 在客户端编译 C#。

我有这些问题:

这种方法是否比用 javascript 编译的 React / Vue.js 运行得更快?

每次页面加载时浏览器都需要下载 WebAssembly 库是真的吗?

在 Internet 上没有任何流行的 JavaScript 框架的性能比较。所以想知道微软新框架的理论性能。

【问题讨论】:

我这篇文章@chris sainty 很好地解释了它。 chrissainty.com/what-is-blazor-and-why-is-it-so-exciting 【参考方案1】:

浏览器是否需要下载 WebAssembly 每次页面加载时的库?

不,浏览器可以缓存文件。用于 Blazor 应用程序的通用 CDNs 可以解决问题。

这个系统是否比编译的 React / Vue.js 更快? 在 JavaScript 中?

Blazor 使用 WebAssembly,理论上 WebAssembly 应该比任何 JavaScript 库都快。然而,并不是所有的浏览器都有成熟的 WebAssembly 解析器。所以你可能会发现目前浏览器不会以最佳速度运行 WebAssembly。

您可以创建一个小型 Blazor 应用程序并在 Firefox、Chrome 或 Edge 中运行它。在大多数情况下,Firefox 运行 Blazor 应用程序的速度比 Chrome 或 Edge 快得多,这意味着浏览器制造商仍然需要改进,甚至 Firefox 也可以改进。

如果您的应用程序需要频繁访问DOM,那么与任何 JavaScript 库相比,WebAssembly / Blazor 肯定会更慢,因为 WebAssembly 无法在不使用 Invokes 的情况下直接访问 DOM(目前速度很慢。请参考下面是我的 Blazor 基准测试)。

在 Firefox 上,10,000 次 RegisteredFunction.InvokeUnmarshalle 调用空方法需要 250 毫秒,而 Chrome 和 Edge 在我的 PC 中需要超过 2400 毫秒。在纯 JavaScript 中,相同场景所需的时间不到 10 毫秒。

此外,Blazor 的当前实现在浏览器的 WebAssembly 引擎之上有自己的 MSIL 引擎,这意味着有两个解释器在工作来运行 Blazor 项目,就像两个翻译器解释对话而不是一个。目前微软正在开发一个AOT 编译器,该编译器尚未发布。一旦发布,Blazor 将比当前的实现快得多。

Mono and WebAssembly - Updates on Static Compilation

我们可以放心地假设 Web 程序集是 Web 开发的未来,但目前我们还不能说 Blazor 的未来。从理论上讲,Blazor 可以比现有的任何框架都快,但是我们需要 WebAssembly 维护人员、浏览器开发人员、微软和社区的承诺,以使理论变得实用。

2018 年 7 月 10 日更新

WebAssembly 存储库中有新提案。

    允许 WebAssembly 直接处理 DOM。 Interface types #8

    带有 GC 的 WebAssembly 的引用类型。 Reference Types for WebAssembly

以上两个提议将为未来 DOM 和 WebAssembly 之间更快的交互铺平道路。换句话说,Blazor 未来会更快。

2018 年 10 月 17 日更新

Firefox 团队能够像调用 JavaScript 到 JavaScript 方法调用一样快地调用 JavaScript 到 WebAssembly。到目前为止,Firefox 在 WebAssembly 支持方面遥遥领先于任何其他浏览器。

Calls between JavaScript and WebAssembly are finally fast

【讨论】:

我的理解是 React 和现在 Angular 等框架非常快的原因之一是虚拟 DOM 概念,与实际 DOM 相比,仅应用差异。这是 Blazor 正在做或计划在未来做的事情吗? @Cleverguy25 Angular 不使用虚拟 DOM...React 使用,这就是为什么 react 会在大型应用程序上提供更好的性能 @Cleverguy25 Blazor 像 React 一样使用虚拟 DOM,这可能会使它变得非常快。 Angular 曾尝试使用虚拟 Dom,但据我所知它已被撤回。 Blazor 有一个虚拟 DOM,以便仅将增量更新应用于 html。它还解释代码,目前没有 wasm 编译。 AOT 编译器推迟到 2021 年第一季度。【参考方案2】:

2021 年 4 月,我们针对旧版 Angular.js Web 应用以及 Flutter Web(HTML 和 CanvasKit 渲染器)进行了 Blazor WASM 试验。我们重新创建了旧版应用程序的主页(本质上是一个带有过滤器、分页、排序等的大数据网格)。以下是一些要点:


                                                                      Lighthouse perf. Scores
                   Grid Displ.  Data transf.  Data uncomp.  Reqs.  FCP   SI   LCP  TTI  TBT  CLS
Blazor*            2.2s         4.7MB         13.7MB        99     0.5s  1.6s 0.5s 2.1s 1.3s 0.01 
Flutter HTML       1.7s         2.1MB          3.7MB        15     1.9s  2.5s 2.2s 2.3  0.2s 0
Flutter CanvasKit^ 2.8s         4.7MB         10.5MB        17     1.0s  2.2s -/-  2.2s 1s   0   
AngularJS`         1.9s         2.0MB          5.7MB        294    2.1s  2.2s 2.6s 2.6s 0.1s 0

网格显示。 - 完全显示网格所需的时间(从时间线和 Lighthouse 收集的屏幕截图来看) 数据传输。 - 加载应用时传输的数据(DevTools 中的网络选项卡,缓存已清除) 数据未压缩。 - 传输数据的未压缩大小(网络选项卡) 要求。 - 加载应用时发出的请求数(网络选项卡,缓存已清除) 灯塔性能得分明细 在 Windows 10、Google Chrome 版本 89.0.4389.128(官方版本,64 位)、Intel Core i5 4460、16GB RAM、有线 LAN 连接上测试 用于构建应用的发布配置、Blazor WASM/.NET 5、Flutter(Channel beta,2.1.0-12.2.pre)、AngularJS 1.7.7

*Lighthouse 给出的 LCP 值不正确(它将 Blazor 的空白“正在加载...”页面计为 LCP)

^Flutter 的 CanvasKit 渲染器不允许 Lighthouse 获取 LCP 测量值

`旧版应用程序比创建的 PoC 大得多,有更多的屏幕和资产会影响应用程序启动时的请求数量

【讨论】:

您是使用带有 gRPC 还是普通 Http 的 Blazor?我认为您可以通过实施 gRPC 获得更好的结果。 Blazor 以及 Flutter 客户端使用 gRPC Web。 Steve Sanderson 在他的博客中写道,Blazor WASM 默认使用 JSON-over-HTTP。所以你必须显式地实现 gRPC。 blog.stevensanderson.com/2020/01/15/… 对不起,但您似乎混淆了概念,并且看起来您没有使用 gRPC 的经验。 gRPC 没有显式或隐式实现,Web 浏览器(以及因此任何 SPA,例如 Blazor)只能通过称为 gRPC Web 的代理通过 HTTP/HTTPs 使用 gRPC。附带说明,使用 gRPC 与上述测试无关,gRPC 可以在从服务器获取的 30-40KB 数据集上给出 -5KB 差异以显示网格,时间差异在脚本编写的大部分时间中是不可见的 我明白你的意思... 上图显示了首次加载应用程序时的总流量 - 这包括 HTML、CSS、JS、WASM 模块、DLL 等。gRPC 流量在第一次加载大约是 30KB(页面中网格的数据),当总数在 5-14 MB 范围内时可以忽略不计【参考方案3】:

据我了解,Blazor 使用 WebAssembly 在客户端编译 C#。

对了一半。您可以将代码写入 WebAssembly (WASM) 客户端(是的,客户端是 C#),但您也可以执行逻辑服务器端。两者都有好处。如果你走 WASM 路线,你的所有代码都是可见的。但它可以比逻辑全部基于服务器的情况更快地重新呈现——但如果它是基于服务器的,则您的代码是不可见的。

这种方法是否比用 JavaScript 编译的 React / Vue.js 运行得更快?

没有。我已经完成了大量的 Vue.js 并且 Vue.js 运行得更快。 但是我可以使用 Blazor 更快地编写代码 很多。 Blazor 提供了一种虚拟滚动解决方案,可以让它看起来更快。在我的情况下,可用的绘图组件太慢了。我使用 C# 和 JavaScript 编写了一个运行良好的 Blazor 组件。大多数时候我不担心 WASM 代码运行太慢...但是绘图需要更快... Blazor 让我有我的蛋糕...我只需要做一些低级别的工作JavaScript。在过去六个月中,Blazor 的执行速度越来越快,该团队表示,当.NET 6 出现时,还有更多的事情要做。但是对于我需要做的 99% 的事情来说,它已经足够快了。

每次页面加载时浏览器都需要下载 WebAssembly 库是真的吗?

如果它们被缓存,则不会。即使他们第一次加载,如果你有一个体面的连接,它也不会很慢。它大约为 10 MB。

一个没有被问到的大问题——它值得使用吗?我已经使用它大约六个月了。

对我来说,这很棒。 C# 是一门非常好的语言。有时我会错过动态添加属性,并且通常您必须手动启动重绘,但使用可空对象检查等功能会警告您没有检查您的代码是否会导致空引用检查——它比 JavaScript 好得多。我经常觉得使用 JavaScript“工具链”很痛苦。能够选择退出 JavaScript 库,真是太好了。

【讨论】:

【参考方案4】:

.NET 6 的 ASP.NET Core 路线图可以在 github here 上找到。你会发现 Blazor 的任务是迄今为止最多的。

请注意,该列表表示 ASP.NET 团队将重点关注的项目意味着他们将重点放在改进 Blazor 上。

本期列出了我们的团队在 .NET 6 时间范围内将重点关注的主要投资清单。 此列表中的项目仅是主要投资领域,不包括我们将在此期间解决的所有功能和错误修复。

以下是他们一直从事的一些任务:

已完成的任务:

    AOT 编译。 将所有内容编译到 WebAssembly

    改进 Blazor 中的 SVG 支持。 Blazor 中 SVG 支持的***问题

    在 JS Interop 中支持字节数组传输。

正在进行的任务

    Blazor 的热重载。 构建性能优化

    暂停和恢复 Blazor 应用程序。

    定位并部署到桌面平台。

    消除 SignalR 消息大小施加的大小限制。

    拖放。 提供用户可以在拖动期间订阅的事件 并放下

【讨论】:

现在对 SVG 的支持确实非常出色。内联 SVG 几乎可以在许多任务中完全取代 HTML。

以上是关于Blazor 性能的主要内容,如果未能解决你的问题,请参考以下文章

Blazor 与 Razor

优化服务器端 Blazor 应用程序

打开MASA Blazor的正确姿势5:插槽

NET 8 预览版 2 亮点是Blazor

Blazor CascadingParameter 与单例 DependencyInjection

Hello Blazor:(10)按需加载JavaScript脚本