原文链接:https://blazor-university.com/overview/what-is-blazor/
什么是 Blazor?
Blazor 是一个单页应用程序开发框架。Blazor 这个名称是单词 Browser 和 Razor(.NET HTML 视图生成引擎)的组合/变异。这意味着 Blazor 不必在服务器上执行 Razor 视图以便将 HTML 呈现给浏览器,而是能够在客户端上执行这些视图。
Blazor 还支持在服务器上执行 SPA。
Blazor 不是什么
Blazor 不像 Silverlight,微软之前在浏览器内托管应用程序的尝试。Silverlight 需要一个浏览器插件才能在客户端上运行,这阻止了它在 iOS 设备上运行。
Blazor 不需要在客户端上安装任何类型的插件即可在浏览器中执行。Blazor 要么运行在服务器端,在这种情况下,它在服务器上执行,浏览器仅作为一个终端,要么通过使用 WebAssembly 在浏览器本身中运行。
因为 WebAssembly 是一种 Web 标准,它在所有主要浏览器上都受支持,这意味着 Blazor 客户端应用程序可以在 Windows/Linux/Mac/Android 和 iOS 上的浏览器中运行。
Blazor 是开源的
Blazor 源代码[1]可在此处获得。源代码归 .NET 基金会[2]所有,该基金会是一个非营利组织,旨在支持基于 .NET 框架的开源项目。
据 .NET 基金会称,在撰写本文时,它得到了 3,700 家公司的支持,并有 61,000 名贡献者。
什么是 WebAssembly?
WebAssembly(简称为“Wasm”)是一个指令集,旨在运行在任何能够解释这些指令或将它们编译为本机机器代码并执行它们的主机上。
Wasm 是一种以特定二进制格式格式化的指令集。因此,任何遵守本规范的主机(硬件或软件)都能够读取二进制文件并执行它们——无论是解释的,还是直接编译成特定于设备的机器语言。
Wasm 类似于 .NET 源代码编译成的通用指令集(通用中间语言)。就像 .NET 一样,Wasm 可以从 C# 等高级语言生成。
Blazor 不需要在客户端上安装 .NET 即可通过 WebAssembly 运行。
支持的浏览器
浏览器 | 最低版本 |
---|---|
Android browser | 67 |
Chrome | 57 |
Chrome for Android | 74 |
Edge | 16 |
Firefox | 52 |
Firefox for Android | 66 |
iOS Safari | 11 |
Opera | 44 |
Opera mobile | 46 |
Safari | 11 |
Samsung Internet | 7.2 |
数据来自 CanIUse.com[3]
Blazor 托管模型
Blazor 目前有两种托管模型, Blazor Server 和 Blazor Web Assembly。服务端托管于 2019 年 9 月发布,Web Assembly 于 2020 年 5 月正式发布。
Blazor Web Assembly
优点
Web Assembly 在客户端的浏览器内部运行,因此可以部署为静态文件。尽管如此,由于浏览器安全限制,Blazor Wasm 应用程序不会直接从本地文件系统运行。
Blazor Wasm 可以离线工作。当与服务器的网络连接丢失时,客户端应用程序可以继续运行(显然它将无法与服务器通信以检索新数据)。
它还可以很容易地作为渐进式 Web 应用程序[4]运行,这意味着客户可以选择将我们的应用程序安装到他们的设备上,并在需要时运行它,而无需任何网络访问。
在客户端机器上运行代码,这意味着服务器负载显著降低。
缺点
blazor.webassembly.js
文件用于引导客户端应用程序。它会下载所有必需的 .NET DLL 程序集,这使得应用程序的启动时间在您的应用程序第一次运行时比服务器端慢(DLL 然后会由浏览器缓存,从而使后续启动更快)。
Mono 框架用于解释 .NET 中间语言,因此比运行 Blazor Server 慢。计划在未来的版本中进行提前 (Ahead-of-time AOT) 编译。
Blazor Wasm 尚不支持多个线程,因此所有处理都发生在 UI 线程上——尽管对服务器/JavaScript 等的调用是异步发生的,所以不要阻止 UI 的响应。
此外,Blazor Wasm 仅适用于较新的浏览器,对搜索引擎不友好(除非我们启用服务器端预渲染)。
Blazor Server
优点
Blazor Server 在将 HTML 内容发送到客户端浏览器之前对其进行预渲染。这使它对搜索引擎友好,并且没有可察觉的启动时间。
Blazor Server 应用程序将在较旧的浏览器(例如 Internet Explorer 11)上运行,因为不需要 Web Assembly,只需要 HTML 和 JavaScript。当代码在服务器上执行时,还可以在 Visual Studio 中调试我们的 .NET 代码。
缺点
Blazor Server 为当前客户端设置内存中会话,并使用 SignalR 在服务器上运行的 .NET 和客户端浏览器之间进行通信。对于所有用户,所有内存和 CPU 的使用都会以服务器为代价。这也意味着客户端与首先为其提供服务的服务器绑定,因此无法使用负载均衡。
初始页面被渲染并发送到浏览器后,blazor.server.js
文件将 hook 浏览器中的任何相关用户交互事件,以便它可以在用户和服务器之间进行通信。例如,如果呈现的元素注册了 @onclick
事件,则 blazor.server.js
将 hook 到其 JavaScript onclick
事件,然后使用其 SignalR 连接将该事件发送到服务器并执行相关的 .NET 代码。
<p>Current count = @CurrentCount
</p>
<button @onclick=IncrementCount>Click me</button>
@code
{private int CurrentCount;public void Increment(){CurrentCount++;}
}
.NET 代码执行完成后,Blazor 将重新渲染页面上的组件,然后将 HTML 的增量包发送回客户端的浏览器,以便它可以更新其显示,而无需重新加载整个页面。
注意: 稍后将深入介绍渲染树。
如果我们运行一个标准的 Blazor 应用程序,单击菜单中的 Counter 链接,然后单击 Click me 按钮,我们可以观察到与服务器之间的 SignalR 数据通信。
在 Chrome 浏览器中运行应用程序。
单击应用程序菜单中的 Counter 链接。
按 F12 打开浏览器的开发者工具。
在开发人员工具窗口中,单击网络选项卡。
重新加载页面。
接下来,单击 WS 选项卡(WebSocket 的缩写)。
单击 _blazor 项以显示套接字数据。
单击 Click me 按钮将显示类似于以下内容的网络流量(为便于阅读而进行了删减和格式化)。
DispatchBrowserEvent{"browserRendererId": 0,"eventHandlerId": 3,"eventArgsType": "mouse","eventFieldInfo": null}{"type": "click","detail": 1,"screenX": 338,"screenY": 211,"clientX": 338,"clientY": 109,"button": 0,"buttons": 0,"ctrlKey": false,"shiftKey": false,"altKey": false,"metaKey": false}
相应的来自服务器的响应如下所示:
注意: 突出显示的 1
表示增量 HTML,并且是计数器的新值。
如果客户端的浏览器和服务器没有关闭或者它们之间的网络连接很慢,特别是当触发状态更改的事件频繁时,这种往返会提供缓慢的体验。例如,诸如 onmousemove
之类的事件会经常触发。
此外,需要大量 HTML 增量更新的更改也可能很慢。例如,如果我们的页面中有一个 HTML <textarea>
组件,它更新了显示区域以在用户键入时预览用户的输入,那么来自服务器的 delta HTML 将随着添加到 <textarea>
中的每个字符而增加。当输入内容变大时,会导致每次按键都进行较大的网络传输。
与 Blazor Wasm 不同,一旦从浏览器到服务器的连接丢失,应用程序就会无响应。Blazor 将尝试重新建立与服务器的连接,但在成功之前,应用程序会显示消息“正在尝试重新连接到服务器……”并阻止所有鼠标与用户界面的交互。
Blazor Mobile Bindings
2020 年 1 月,Microsoft 宣布了 Blazor Mobile Bindings,这是一个实验性项目,允许开发人员结合使用 Blazor 和 Xamarin.Forms (XAML) 的 Razor 变体来构建本机移动应用程序。
你可以在这里[5]找到官方公告。
安装 Blazor
服务器端 Blazor 和 Blazor WebAssembly 现在都作为 .NET Core 3.2.0 的一部分发布。安装 Blazor 现在就像安装 Visual Studio 16.6 或更高版本一样简单!您可以通过此链接[6]下载最新版本的 Visual Studio。
安装时,请确保在 Workloads 选项卡下选择选项 ASP.NET 和 Web 开发。
创建项目
打开 Visual Studio。
单击创建新项目。
在搜索框中键入 Blazor。
选择 Blazor WebAssembly 应用。
点击下一步。
输入项目名称,例如 MyFirstBlazorApp。
点击下一步。
选中 ASP.NET Core 托管复选框。
单击创建。
创建页面
在 Blazor 中,页面是可以通过 URL 访问的顶级视图。在本练习中,我们将从头开始重新创建 Counter.razor
页面。
在解决方案资源管理器窗口中,展开
MyFirstBlazorApp.Client
项目。展开
Pages
文件夹。右键单击 ·Counter.razor· 并将其删除。
右键单击
Pages
文件夹。选择 添加->Razor 页面 并创建一个名为
Counter.razor
的新页面。如果您收到“脚手架”错误,您可以选择另一种文件格式并为其指定.razor
文件扩展名。
Razor 页面是一个独立的视图。我们可以包含 HTML 和 Razor 视图标记,以及事件等所需的任何 C# 方法。使用以下内容启动新的 Razor 页面。
@page "/counter"
<h1>Counter</h1>
<p>The counter value is @currentCount</p>
@code {private int currentCount= 42;
}
第一行标识呈现此页面内容所需的 URL。路由部分将介绍更高级的路由技术。
接下来是一些标准的 HTML,一个带有页面标题的 H1 和一个带有一些内容的段落。就像使用标准 ASP.NET Razor 页面一样,可以通过使用 @
符号对其进行转义来插入可编程内容。在本示例中,我们将显示 currentCount
私有成员的值。
最后,声明页面的 @code
节。这是我们编写属性/方法、事件处理程序或其他任何我们需要的代码的地方。这里我们声明了 currentCount
私有成员和设置它的初始值。运行应用程序,单击页面左侧的 Counter 链接,您应该会看到如下内容:
与页面交互
到目前为止,我们已经绑定了页面的私有成员,以便在呈现 Razor 视图时将其值作为 HTML 输出。接下来,我们将更新该值作为对用户操作的响应。
更改 razor 视图以包含以下按钮标记。
<button class="btn btn-primary" @onclick=IncrementCount>Increment counter</button>
这将添加一个 HTML 按钮并使用一些 Bootstrap 样式使其看起来更漂亮。它还将其 onclick
事件设置为执行名为 IncrementCounter
的方法。方法实现非常简单,放在 @code
节。
@page "/counter"
<h1>Counter</h1>
<p>The counter value is @currentCount</p>
<button class="btn btn-primary" @onclick=IncrementCounter>Increment counter</button>
@code {private int currentCount = 42;private void IncrementCounter(){currentCount++;}
}
现在再次运行应用程序,导航到 Counter 页面,然后单击按钮查看页面更新的值。
参考资料
[1]
Blazor 源代码: https://dotnetfoundation.org/
[2].NET 基金会: https://dotnetfoundation.org/
[3]CanIUse.com: https://caniuse.com/#search=wasm
[4]渐进式 Web 应用程序: https://web.dev/progressive-web-apps/
[5]这里: https://devblogs.microsoft.com/aspnet/mobile-blazor-bindings-experiment/
[6]此链接: https://visualstudio.microsoft.com/vs/