Blazor实战 第一章

1 开始您的 Blazor 之旅


本章包括 \- 为下一次应用选择 Blazor 的理由 - 为什么组件是构建用户界面的更好方法? - Blazor 的托管模式 我们生活在一个激动人心的时代,.NET 开发人员的生活从未如此美好。我们可以为任何操作系统(Windows、Linux、iOS、Android 或 macOS)创建应用程序,当然,我们还可以使用 [ASP.NET](http://ASP.NET) MVC、Razor Pages 和 Web API 构建令人惊叹的网络应用程序,多年来,这些技术使我们能够创建稳健、可扩展和可靠的系统。

然而,这块拼图一直缺少一块。所有 [ASP.NET](http://ASP.NET) 网络解决方案都有一个共同点,那就是它们都基于服务器。 我们一直无法利用 C# 和 .NET 的强大功能来编写客户端网络应用程序;这一直是 JavaScript 的天下,但现在不是了。

在本章中,我将向你介绍一个名为 Blazor 的革命性客户端框架。Blazor基于网络标准,允许我们使用C#和.NET编写内容丰富、引人入胜的用户界面。我们将探讨 Blazor 如何使您的开发过程更加高效,提高您的生产力水平,尤其是当您在服务器上也使用 .NET 时。我们将介绍托管模型,这是开始使用 Blazor 时需要了解的一个重要概念。接下来,我们将开始探索组件以及使用组件构建用户界面的好处。最后,我们将讨论您下一个项目应该考虑 Blazor 的原因。

1.1为何选择 Blazor 进行新应用?

可以说,近来启动一个新项目最难的部分就是选择技术栈--可供选择的技术实在太多了。 在前端领域尤其如此。我们必须选择一个框架(Angular、React、Vue.js),选择一种语言(TypeScript、CoffeeScript、Dart),选择一种构建工具(webpack、Parcel、Browserify)。如果一个团队是这个生态系统的新员,要想找出哪种技术组合能帮助项目取得成功,似乎是一项几乎不可能完成的任务;对于有经验的团队来说,这甚至是一件难事!

让我们来谈谈在下一个项目中选择Blazor的一些主要原因,以及Blazor如何帮助您避免我刚才提到的一些问题。

  • C#,一种功能丰富的现代语言--Blazor 由 C# 提供支持,根据 2021 年 Stack Overflow 开发人员调查 ([http://mng.bz/p240](http://mng.bz/p240)) 显示,C# 是第八大最受欢迎的语言。它功能强大、简单易学、用途广泛。虽然 C# 是一种面向对象的语言,但它正在采用越来越多的功能,以实现更实用的方法(如果您喜欢的话)。静态类型可以帮助开发人员在构建时捕捉错误,使开发生命周期更快、更高效。静态类型语言已经存在了很长时间,目前是第十个版本。它稳定、设计精良、支持良好。
  • 强大的工具--.NET 社区有幸拥有一些令人惊叹的工具。Visual Studio 是一个极其强大、功能丰富且可扩展的集成开发环境(IDE)。对于个人、开源工作或最多 5 人的非企业团队来说,它也是 100% 免费的。如果你更喜欢轻量级的,那么还有 Visual Studio Code(VS Code),它是当今最流行的代码编辑器之一。Visual Studio 和 VS Code 都可以跨平台使用。Visual Studio 适用于 Windows 和 macOS,而 VS Code 适用于 Windows、macOS 和 Linux。 此外,JetBrains 还推出了一款名为 Rider 的优秀第三方集成开发环境,可跨平台运行于 Windows、macOS 和 Linux。
  • .NET生态系统--许多新框架需要等待生态系统的建立,而Blazor可以利用现有的.NET生态系统。在撰写本文时,[Blazor应用程序以.NET](http://xn--Blazor-8x8ij38hjba2855bgil.NET) 6为目标,理论上可以使用任何兼容的NuGet软件包。我说的是 "理论上",因为有些软件包执行的操作在 WebAssembly 环境中是不允许的,比如修改文件系统。
  • 中立--其他框架规定了应用程序的编写方式,而Blazor没有。Blazor开发没有首选模式或实践;您可以使用自己熟悉和熟悉的模式或实践编写应用程序。如果您喜欢MVVM(模型-视图-视图模型),那就使用它吧。如果您喜欢使用 Redux,那就用它吧。选择权在你手中。
  • 浅显的学习曲线--如果您是一名现有的.NET开发人员,那么Blazor的学习曲线将非常浅显。Razor、C#、依赖注入和项目结构对您来说都是耳熟能详的,而且Blazor不依赖于任何模式,您只需使用自己熟悉并有成效的东西即可。这意味着你可以专注于更快地编写功能,而不是学习框架。
  • 代码共享--如果您在服务器上使用的是C#,那么Blazor就是一个绝佳的搭配。不同的客户端和服务器语言最令人头疼的问题之一就是无法重用代码。模型或数据传输对象(DTO)必须在服务器和客户端之间复制;它们需要保持更新和同步。这可以是一个手动过程,也可以通过某种代码生成实现自动化,但这只是另一件需要设置和维护的事情。有了 Blazor,一切都是 C#。任何共享代码都可以放在一个通用的.NET类库中,并在服务器和客户端之间轻松共享。
  • 开放源代码--与微软的许多项目一样,Blazor完全开放源代码,代码可在GitHub上自由浏览、下载,或叉出自己的副本。团队以开放的方式工作,并以开发人员的要求和反馈为指导。如果你愿意,甚至可以贡献自己的力量。

 1.2组件,构建用户界面的更好方法

与许多现代前端框架一样,Blazor 使用组件概念来构建用户界面。一切都是组件--页面、页面的一部分、布局。在Blazor中有多种类型的组件,以及设计组件的多种方法,这些都将在以后的章节中探讨。不过,学会从组件的角度思考问题对于编写 Blazor 应用程序至关重要。

1.2.1 什么是组件?

把一个组件看作是一个积木。你可以将这些积木组合在一起,形成你的应用程序。这些构件可大可小,由你决定;但是,将整个用户界面作为一个单独的组件来构建并不是一个好主意。当组件被用来划分用户界面的逻辑区域时,才真正显示出它的优势。让我们来看一个用户界面组件化的例子(图 1.1)。

Blazor实战 第一章_第1张图片

图 1.1 按组件划分的布局示例

界面的每个区域都是一个组件,每个组件都有一定的责任。你可能还会注意到,这里形成了一个层次结构。布局组件位于树的顶端;菜单、页眉、主页和页脚都是布局组件的子组件。这些子组件可以而且很可能会有自己的子组件。例如,页眉组件可以包含一个徽标组件和一个搜索组件(图 1.2)。

图 1.2 将组件嵌套成组件树的示例

1.2.2 基于组件的用户界面的优势

许多用户界面中都有重复元素。使用组件的一大优势是,您可以在组件中定义元素,然后在元素重复出现时重复使用该组件。这可以大大减少应用程序中重复代码的数量。它还能大大提高应用程序的可维护性--如果元素的设计发生变化,只需在一个地方进行更新即可。

为了迎合更高级的应用场景,组件可以定义自己的应用程序接口(API),允许数据和事件传入和传出。想象一下业务线应用程序。可以肯定的是,在该应用程序中,有许多地方都以表格格式显示数据。一种方法是将每个表格创建为自己的组件,但这意味着我们最终会有很多组件在表格中显示数据。更好的方法是定义一个组件,将数据集作为参数,然后将其显示在表格中。现在,我们有了一个用于在表格中显示数据的组件,可以在整个应用程序中重复使用。我们还可以为该组件添加排序或分页等功能。这样,应用程序中的所有表都可以自动使用这一功能,因为它们都在重复使用同一个组件。

虽然组件通常都是独立的,但也有可能通过相互协作来创建更复杂的用户界面。例如,以我们刚才谈到的数据表为例,它可以是一个单独的组件,但有可能非常庞大。另一种方法是将其分为几个较小的组件,每个组件都执行特定的工作。我们可以有一个表头组件、一个表体组件,甚至一个表格单元格组件。这些组件各自执行特定的工作,但它们仍然是整个表格组件的一部分。

1.2.3 Blazor 组件剖析

既然我们已经对组件有了一个大致的了解,那就让我们来看看 Blazor 中组件的一个示例。为此,我们将从 Blazor 项目模板中抓取一个组件。图 1.3 显示了 Blazor 标准项目模板 Counter.razor 中的一个组件示例。

Blazor实战 第一章_第2张图片

图 1.3 Blazor 中组件的各个部分

这个特殊的组件被称为可路由组件,因为它的顶部声明了一个页面指令。可路由组件本质上是应用程序中的一个页面。当用户导航到应用程序中的/counter路由时,Blazor路由器将加载该组件。它通过一个按钮显示一个简单的计数器,当用户点击按钮时,计数器的数值会递增一个,并向用户显示新的数值。

虽然现在理解代码并不重要,但我们可以理解组件的结构。图 1.3 分成三个部分,每个部分都有一定的职责。

  • 第 1 部分-用于定义指令、添加 using 语句、注入依赖关系或其他适用于整个组件的一般配置。
  • 第 2 部分--定义组件的标记;使用 Razor 语言编写,该语言是 C# 和 HTML 的混合语言。在这里,我们定义了组成组件的可视化元素。
  • 第 3 部分--代码块。用于定义组件的逻辑。在这部分中可以写入任何有效的 C# 代码。您可以定义字段、属性,甚至整个类。

在本书接下来的内容中,我们将更详细地介绍组件,所以现在就不多说了。不过,这已经让你了解了 Blazor 中组件的外观和组成方式。

1.3 Blazor,使用 C# 构建现代用户界面的平台

Blazor 是一个功能齐全的框架,可利用 C# 和 .NET 的强大功能构建现代客户端应用程序。这样,开发人员就能构建几乎适用于任何平台(包括网络、移动和桌面)的引人入胜的应用程序。

Blazor 是 Angular、Vue.js 和 React 等 JavaScript 框架和库的替代品。如果您有过使用这些技术的经验,那么您可能会发现一些熟悉的概念。最显著的影响是使用组件构建用户界面的能力,这是所有这些技术共享的概念,我们将在本章稍后部分详细探讨。

因为Blazor是建立在网络标准之上的,[所以它不需要终端用户在机器上安装.NET](http://xn--fhqf16de7uo1ad5qlb098ghct12exk1bcro3ylb77akkco50g.NET),也不需要任何浏览器插件或扩展。事实上,有了 Blazor WebAssembly 应用程序,我们甚至不需要在服务器上运行 .NET;这种 Blazor 可以作为简单的静态文件托管。

基于 .NET 构建意味着我们可以访问 NuGet 上充满活力的软件包生态系统。我们拥有一流的工具,包括 Visual Studio、VS Code 和 JetBrains Rider。此外,由于.NET是跨平台的,我们可以在任何我们喜欢的平台上开发我们的Blazor应用程序,无论是Windows、macOS还是Linux。

虽然本书将重点介绍用于网络应用程序开发的Blazor,但我想强调的是,Blazor的编程模型也可用于构建跨平台的桌面应用程序。[随着.NET](http://xn--u2yv18d.NET) 6的推出,Blazor Hybrid也被引入。它建立在新的.NET多平台应用程序用户界面(又称MAUI)框架之上,工作方式与Electron应用程序类似。Blazor应用程序的内容通过BlazorWebView控件呈现。这为这些应用程序的结构提供了很多选择。开发人员可以使用 Blazor 和网络技术来构建整个用户界面,但 Chrome 浏览器除外,它是应用程序的最外层容器,包括标题栏。开发人员也可以只使用 Blazor 编写界面中的特定部分,并将其与本地控件放在一起。

不仅如此。有一个名为 Mobile Blazor Bindings ([http://mng.bz/OGOO](http://mng.bz/OGOO)) 的实验项目已经运行了很长时间。这是 [ASP.NET](http://ASP.NET) Core 团队和 .NET MAUI 团队的合作项目,旨在研究使用 Blazor 编程模型构建本地移动应用程序的潜力和需求!这确实让 Blazor 成为一项值得学习的技术,因为一旦了解了它,开发人员就可以为几乎所有平台或设备构建用户界面。

希望您已经看到,Blazor 是一项令人兴奋的技术,具有很大的潜力。但是,在我们继续深入研究之前,有一个关键概念必须了解,那就是托管模式。接下来,让我们来解决这个问题。

1.3.1 了解托管模式

刚开始使用 Blazor 时,您会立即遇到托管模式。从本质上讲,托管模式就是运行Blazor应用程序的地方。目前,Blazor有两种网络专用托管模型--Blazor WebAssembly和Blazor Server。无论您为应用程序选择哪种托管模式,组件模式都是相同的,这意味着组件的编写方式相同,并可在任一托管模式之间互换(图 1.4)。

Blazor实战 第一章_第3张图片

图 1.4 Blazor 将托管模型与应用程序/组件模型分开。这意味着为一种托管模式编写的组件可用于另一种托管模式。

图 1.4 显示了 Blazor 架构的抽象示意图,包括应用程序和组件模型与各种托管模型之间的分离。Blazor 的一个有趣之处在于,随着时间的推移,其他托管模式也有可能出现。这使得 Blazor 可以在更多地方运行,并用于创建更多类型的用户界面。

1.3.2 Blazor WebAssembly

Blazor WebAssembly允许您的应用程序完全在客户端浏览器中运行,因此它可以直接替代JavaScript SPA(单页面应用程序)框架。为了帮助您了解这种托管模式的工作原理,我们将介绍初始化 Blazor WebAssembly 应用程序的过程(图 1.5)。

Blazor实战 第一章_第4张图片

图 1.5 Blazor WebAssembly 应用程序启动,显示客户端浏览器与网络服务器之间的交互情况

当浏览器向网络服务器发出请求时,整个过程就开始了。网络服务器将返回一组加载应用程序所需的文件。这些文件包括应用程序的主机页面(通常称为 index.html)、应用程序所需的任何静态资产(如图像)、CSS 和 JavaScript,以及一个称为blazor.webassembly.js 的特殊 JavaScript 文件。

在 Blazor WebAssembly 托管模式中,Blazor 框架的一部分位于 JavaScript 中,并包含在 blazor.webassembly.js 文件中。这部分框架主要做三件事:

  •  在浏览器中加载并初始化 Blazor 应用程序
  •  提供直接的 DOM(文档对象模型)操作,以便 Blazor 执行用户界面更新
  • 为 JavaScript 互操作场景提供应用程序接口,我们将在后面的章节中详细讨论这些应用程序接口

说到这里,您可能会好奇为什么我们要编写 JavaScript 文件。Blazor的一大卖点就是可以使用C#而不是JavaScript编写用户界面逻辑,对吗?是的,没错。但就目前而言,WebAssembly 有一个很大的限制:它不能改变 DOM 或直接调用 Web API。WebAssembly 的下一阶段计划并正在开发这些功能,但在它们出现之前,JavaScript 是执行这些任务的唯一方法。

将来有可能不再需要这个文件。这将取决于 WebAssembly 新增功能和浏览器采用这些功能的速度。但现在,它还是框架的重要组成部分。

既然我们已经弄清了这一点,那就继续启动 Blazor 应用程序吧。我想指出的是,从服务器返回的文件都是静态文件;它们不需要任何服务器端编译或操作。这意味着它们可以托管在任何提供静态托管的服务上。服务器上不需要 .NET 运行时。这是首次向 .NET 开发人员开放 GitHub 页面等免费托管选项(仅适用于独立的 Blazor WebAssembly 应用程序)。

浏览器从网络服务器接收到所有初始文件后,就可以处理这些文件并构建 DOM。接下来,浏览器将执行 blazor.webassembly.js。它会执行许多操作,但在启动 Blazor WebAssembly 应用程序时,它会下载一个名为 blazor.boot.json 的文件。该文件包含运行应用程序所需的所有框架和应用程序文件的清单。下载完成后,它将用于下载运行应用程序所需的其余文件。

这些文件大多是普通的 .NET 程序集,没有什么特别之处,可以在任何兼容的 .NET 运行时上运行。但也有另一种下载文件,名为 dotnet.wasm。这个文件是一个完整的 .NET 运行时,已经编译成了 WebAssembly。

WebAssembly WebAssembly 是一种类似汇编语言的低级语言,可在现代网络浏览器中运行,性能接近原生语言。虽然可以直接编写 WebAssembly,但它更常用作 C/C++ 和 Rust 等高级语言的编译目标。WebAssembly 设计为与 JavaScript 同时运行,允许 JavaScript 调用 WebAssembly,反之亦然。WebAssembly 与 JavaScript 应用程序一样,在相同的安全沙箱中运行。有关 WebAssembly 的详细信息,请访问 [https://webassembly.org](https://webassembly.org)。

默认情况下,只有 .NET 运行时编译为 WebAssembly--框架和应用程序文件是标准的 .NET 程序集。不过,.NET 6 引入了 AOT(超前)模式,允许开发人员将应用程序编译为 WebAssembly。这样做的好处是大大提高了 CPU 密集型代码的性能。使用 AOT,编译为 WebAssembly 的 CPU 密集型代码的性能将比默认使用的解释型方法高出许多倍。不过,这也有代价,那就是代码的大小。AOT 编译的代码比标准程序集大两倍左右,这意味着应用程序的总下载量要大得多。

下载完 blazor.boot.json 文件并下载了其中列出的文件后,就到了运行应用程序的时候了。初始化 WebAssembly .NET 运行时,然后加载 Blazor 框架,最后加载应用程序本身。至此,我们就有了一个运行中的 Blazor 应用程序,它完全存在于客户端的浏览器中。除了请求额外数据(如适用)外,它不再依赖服务器。

计算 UI 更新

我们现在了解了 Blazor WebAssembly 应用程序是如何启动的。但用户界面更新是如何计算的呢?就像初始化过程一样,我们将按照一个场景来理解这个过程是如何发生的,以及 Blazor 是如何做的(图 1.6)。

Blazor实战 第一章_第5张图片

图 1.6 Blazor WebAssembly 中从点击链接到应用用户界面更新的客户端导航过程

在我们的方案中,我们有一个 Blazor WebAssembly 应用程序,其中有两个页面只包含一个页眉: 分别是主页和计数器。用户在应用程序的主页上,点击链接进入计数器页面。在从主页导航到计数器页面时,我们将跟踪 Blazor 更新用户界面的过程。

当用户点击计数器链接时,导航事件会被 Blazor 的 JavaScript 运行时(blazor.webassembly.js)拦截。然后,该事件被传递给运行在 WebAssembly 运行时 (dotnet.wasm) 上的 Blazor 框架,并由 Blazor 的路由器组件进行处理。

路由器会检查路由表,寻找与用户试图导航的路由相匹配的可路由组件。在我们的例子中,它会找到与 Counter 组件匹配的组件,创建该组件的新实例,并执行相关的生命周期方法。

完成后,Blazor 将计算出更新 DOM 以匹配计数器组件所需的最小更改次数。完成后,这些更改将传回 Blazor JavaScript 运行时,然后将这些更改应用到物理 DOM。此时,用户界面将更新,用户将进入计数器页面。

所有这一切都发生在用户浏览器的客户端。在这个过程中,任何时候都不需要服务器。可以说,在现实世界的应用程序中,你很可能会在这个过程的某个阶段调用服务器。这通常发生在执行被导航组件的生命周期方法时,以便为组件加载一些初始数据。但这取决于具体的应用程序。

效益和权衡

既然我们已经对 Blazor WebAssembly 托管模式的工作原理有了一定的了解,下面我们就来谈谈选择这种模式的好处和利弊。先说好处:

  • 应用程序在客户端运行--这意味着服务器上的负载大大减少,因此可以将大部分工作卸载到客户端。这可以大大节省服务器基础设施的成本,并提高应用程序的可扩展性。
  • 可在离线情况下运行--由于应用程序完全在浏览器内运行,因此无需与服务器建立持久连接,从而使应用程序更能承受不稳定的网络连接。启用渐进式网络应用(PWA)功能也很简单。事实上,Blazor WebAssembly 将此作为一个选项,您可以在创建应用程序时进行选择。
  • 以静态文件形式部署--由于Blazor WebAssembly应用程序只是静态文件,因此它们可以部署到任何有静态主机的地方。这为.NET开发人员提供了一些历史上从未有过的选择。GitHub 页面、Netlify、Azure Blob Storage、AWS(亚马逊网络服务)S3 buckets 和 Azure Static Web Apps 等服务都是托管独立 Blazor WebAssembly 应用程序的选择。部署静态文件的成本相对低于在各主要云提供商托管网络应用程序的成本。
  • 代码共享--Blazor WebAssembly的最大优势之一可能是在服务器上使用C#。现在,您可以在客户端使用与服务器上相同的 C# 对象。让TypeScript模型与C#模型保持同步,反之亦然的日子一去不复返了。

当然,没有什么是万能的,让我们来了解一下这种模式的一些权衡:

  • 有效载荷--与某些 JavaScript 应用程序相比,Blazor 应用程序的初始下载大小可能要大得多(不过每次发布时都会有所改进)。一个最小的 Blazor 应用程序在发布时大约只有 1 MB,但其他应用程序可能大得多。每个应用程序都不一样,Blazor 应用程序也没有标准大小。不过,这只是一次性成本,因为运行时和许多框架程序集都会在首次加载时缓存,这意味着后续加载可能只有几 KB。
  • 加载时间--有效载荷大小的连锁反应可能是加载时间。如果用户的网络连接较差,下载初始文件所需的时间会更长,这会延迟应用程序的启动,给用户留下一条加载信息。使用服务器端预渲染可以稍稍弥补这一点;不过,虽然这将给用户带来更有趣的初始外观,但在下载和初始化所有文件之前,应用程序仍无法进行交互。Blazor WebAssembly 应用程序的服务器端预渲染还需要在服务器上安装 [ASP.NET](http://ASP.NET) Core 元素,因此无法选择任何免费托管服务。
  • 运行时受限--可以说这并不是一个权衡的问题,但对于习惯于相对自由地控制应用程序运行机器的现有 .NET 开发人员来说,这是需要注意的。WebAssembly 应用程序与 JavaScript 应用程序一样,运行在相同的浏览器沙盒中。举例来说,这意味着你将不被允许进入用户的机器,做一些诸如访问本地文件系统之类的事情。
  • 代码安全性--就像 JavaScript 应用程序一样,您的代码是在浏览器中下载和运行的。因此,用户可以访问您的应用程序 DLL。这意味着您不应在Blazor WebAssembly应用程序中包含任何包含知识产权的代码。任何有价值的代码都应作为 API 的一部分保存在服务器上。

总而言之,如果您想替换Angular、React或Vue.js等JavaScript SPA框架,那么Blazor WebAssembly是您应该选择的托管模式。虽然需要考虑一些取舍,但选择这种模式也有一些实质性的好处。

1.3.3 Blazor 服务器

既然我们已经了解了Blazor WebAssembly是如何工作的,那么让我们把目光转向服务器托管模式,看看它有什么不同。Blazor Server是Blazor第一个支持生产的托管模式,比WebAssembly版本早8个月左右发布。与之前的托管模式一样,我们将通过初始化一个 Blazor Server 应用程序来帮助你理解其工作原理(图 1.7)。

Blazor实战 第一章_第6张图片

图 1.7 Blazor 服务器应用程序的启动过程

这一过程始于浏览器加载网站的请求。当该请求到达网络服务器时,可能会发生两种情况:启动应用程序,或者如果应用程序已经在运行,则建立一个新的会话。为什么应用程序已经在运行?Blazor WebAssembly的行为更像桌面应用程序,每个用户都有自己的实例,而Blazor服务器则不同,它运行的是所有用户都能连接的应用程序实例。因此,应用程序可能已经在运行,新请求只是建立一个新会话。每个用户都有自己的应用程序实例,该实例在他们的机器上本地运行。Blazor 服务器则不同,服务器上只运行一个应用程序实例,但可以支持多个客户端。因此,应用程序可能已经在运行,新请求只会建立一个新会话。

然后,应用程序对请求进行处理,并将初始有效载荷发送回浏览器。这包括 CSS、JavaScript 文件和图片等静态资产。此外还有初始 HTML,但这是经过编译的,而不是我们在 Blazor WebAssembly 中看到的静态 HTML。这是因为Blazor服务器应用程序的托管页面是Razor页面,而不是WebAssembly模型中的静态HTML页面。这样做的好处是允许Blazor服务器应用程序开箱即用服务器端预渲染。事实上,在创建此类 Blazor 应用程序时,该功能已默认启用。

一旦初始有效载荷返回浏览器,文件得到处理并创建了 DOM,然后一个名为 blazor.server.js 的文件就会被执行。该运行时的任务是建立一个 SignalR 连接,返回服务器上运行的 Blazor 应用程序。至此,应用程序就完全启动并准备好与用户交互了。

您可能已经发现了这一点,但整个过程与 Blazor WebAssembly 的工作方式并无不同,只是在 SignalR 连接上稍作了延伸。Blazor Server 和 Angular、Vue.js 或 Blazor WebAssembly 一样,都是 SPA。它只是碰巧在服务器上而不是客户端运行其逻辑并计算 UI 更新。事实上,我敢打赌,如果你看到两个完全相同的应用程序,一个是用 Blazor Server 编写的,一个是用 Blazor WebAssembly 编写的,作为用户,你肯定分辨不出它们之间的区别。

性能

在讨论这种模式的优势和权衡之前,我想先简单提一下性能。由于这种托管模式会产生大量的网络聊天,您可能会想,这种托管模式的扩展性是否会特别好。

2019 年,[ASP.NET](http://ASP.NET) Core 团队进行了一些测试,以确定 Blazor Server 应用程序的性能水平。他们在 Azure 中设置了一个应用程序,并在不同功率的虚拟机上进行了测试,检查应用程序可支持的活跃用户数量。以下是测试结果:

  •  标准 D1 v2 实例(1 个 vCPU 和 3.5 GB 内存)--并发用户超过 5,000 人
  • 标准 D3 v2 实例(4 个 vCPU 和 14 GB 内存)--并发用户超过 20,000 人

如您所见,Blazor 服务器在性能方面毫不逊色。团队发现,影响可支持客户端数量的主要因素是内存。这是有道理的,因为服务器需要跟踪连接到它的所有客户端--客户端越多,需要存储在内存中的信息就越多。

测试的另一个主要发现是网络延迟对应用程序的影响。由于所有交互都要发回服务器进行处理,因此延迟会对可用性产生很大影响。如果服务器距离客户端 250 毫秒(ms),那么每次交互至少需要 500 毫秒才能处理完毕,因为交互必须先传送到服务器(250 毫秒),然后处理,最后再传送回来(250 毫秒)。

测试发现,当延迟超过 200 毫秒时,用户界面就会开始感觉迟钝,响应速度降低。一般来说,您总是希望您的用户与服务器位于同一大洲。如果您想拥有一个全球可用的 Blazor 服务器应用程序,那么您就需要让应用程序均匀地分布在世界各地,并将所有客户端与服务器之间的时延控制在 200 毫秒以内。

效益和权衡

和以前一样,让我们来看看选择 Blazor 服务器应用程序的好处和利弊。

  • 有效载荷小--由于应用程序是在服务器上运行,而不是在客户端运行,因此初始下载量要小得多。根据CSS和图片等静态资产的不同,Blazor服务器应用程序的体积可小至100-200 KB。
  •  快速加载时间--由于有效载荷小得多,应用程序的加载速度也快得多。服务器端预渲染也有帮助,因为用户永远不会看到加载信息。
  • 访问完整的运行时--应用程序代码是在服务器上完整的 .NET 运行时之上执行的。这意味着您可以在必要时访问服务器的文件系统,而不会受到任何安全限制。
  • 代码安全--如果您的代码是专有的,而且您不希望别人下载和查询这些代码,那么Blazor服务器就是一个不错的选择。应用程序代码全部在服务器上执行,只有用户界面更新会发送到客户端。这意味着您的代码绝不会以任何方式暴露给客户端。

Blazor 服务器有很多优点,但如何取舍呢?

  • 服务器负载过重--Blazor WebAssembly 允许我们利用客户端的强大功能,而 Blazor Server 则完全相反。现在几乎所有的工作都由服务器来完成。这意味着您可能需要在基础架构上投入更多资金来支持Blazor服务器应用程序。根据应用程序的规模,可能还需要进行负载均衡,以正确管理 Blazor Sever 使用的基于 SignalR 的会话。
  • 无法脱机工作--Blazor WebAssembly可以轻松脱机工作,而Blazor服务器却不行。SignalR连接是应用程序的生命线,没有它,客户端根本无法运行。默认情况下,这将导致覆盖一条信息,说明客户端正在尝试重新建立连接。如果失败,用户必须刷新浏览器才能重新启动应用程序。
  • 延迟--由于其设计,Blazor服务器应用程序对延迟问题非常敏感。用户与应用程序的每一次交互都必须发回服务器进行处理,并等待任何需要应用的更新。如果客户端与服务器之间的连接延迟过高,用户界面就会出现明显的延迟,操作也会很快感觉迟缓。在实际数据中,超过 200 毫秒的延迟就会开始导致这些问题。
  • 需要稳定的连接--Blazor服务器应用程序需要稳定的网络连接,以满足低延迟的需求,并与无法离线工作相联系。如果连接时断时续,用户就会在应用程序中不断看到重新连接的覆盖图,这很快就会造成严重干扰。出现这种情况的一个明显场景是用户使用的移动设备连接时断时续。

    

总之,如果您正在寻找一个快速加载的应用程序,并且您的用户拥有快速稳定的网络连接,那么 Blazor 服务器就是一个不错的选择。选择这种托管模式,您还可以获得代码安全保障。

1.3.4 其他托管模式

在结束本章之前,我想让大家了解另外两种托管模式--Blazor混合托管和Blazor移动绑定。我不会详细介绍这两种模式,因为它们不是本书的重点,但知道它们的存在可以说明使用Blazor可以构建的范围。

BLAZOR HYBRID

Blazor Hybrid基于.NET MAUI框架的技术,允许开发人员使用Blazor编写跨平台桌面应用程序。与 Blazor WebAssembly 和 Blazor Server 一样,组件使用 C#、HTML 和 CSS 编写,并使用名为 BlazorWebView 的控件呈现。下面的列表显示了一个在 Blazor Hybrid 应用程序中运行的组件示例。

清单 1.1 在 Blazor Hybrid 上运行的组件

Current count: @currentCount

@code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }

Blazor Hybrid 的一大优势是,它可以运行同样可以在 Blazor WebAssembly 或 Blazor Server 中运行的组件。清单 1.1 中显示的代码可以在这三种托管模式下执行,无需做任何修改。

MOBILE BLAZOR BINDINGS

Mobile Blazor Bindings 是一种试验性托管模式,它采用了一种不同的组件编写方法。该托管模式的组件必须使用本地控件编写。以下列表包含与列表 1.1 相同的组件,但针对移动 Blazor Bindings 托管模式进行了重写。

清单 1.2 在 Mobile Blazor Bindings上运行的组件


    
    

 
@code {
    private int currentCount = 0;
 
    private void IncrementCount()
    {
        currentCount++;
    }
}

正如您所看到的,这两个代码示例的编程模型是相同的。代码块中的逻辑没有变化;毕竟这只是 C#。唯一不同的是标记,网络技术被换成了本地移动控件。这意味着我们不能在基于网络的托管模型和本地托管模型之间交换组件。不过,一旦我们掌握了 Blazor 的编程模型,就可以轻松地利用这些知识创建其他类型的用户界面。

摘要

本章介绍了 Blazor 框架。我们介绍了 Blazor 的许多强大功能,还介绍了许多现在可能还不太明白的概念。别担心,在接下来的章节中,我们将详细探讨所有这些内容。现在,这里是我们所涉及内容的总结:

  • Blazor 允许开发人员利用 C# 和 .NET 的强大功能创建丰富的交互式用户界面,而无需 JavaScript。
  •  Blazor 是一个 SPA 框架,可以通过 WebAssembly(一种开放式网络标准)完全在浏览器内运行,也可以在服务器上利用 SignalR 连接将客户端浏览器与应用程序连接起来。
  • Blazor WebAssembly 可用于任何现有的服务器技术。不过,将它与 [ASP.NET](http://ASP.NET) Core 后端一起使用会有真正的好处,因为代码可以通过 .NET 类库轻松共享。
  • 应用程序是使用组件编写的。通过组件,我们可以创建独立的用户界面,这些用户界面既可以单独工作,也可以相互组合。

你可能感兴趣的:(Blazor,c#)