Blazor vs React:.NET 开发者的诚实比较

发布: (2025年12月7日 GMT+8 11:40)
8 min read
原文: Dev.to

Source: Dev.to

什么是 Blazor?

Blazor 是微软的框架,用 C# 而不是 JavaScript 来构建交互式 Web UI。名字是 Browser(浏览器)和 Razor(.NET 模板语法)的组合,自 2020 年起已进入生产环境。

核心思想是你编写的 C# 可以:

  • 在服务器上运行(Blazor Server) – 你的 C# 在服务器上执行,UI 更新通过 SignalR WebSocket 实时推送到浏览器。
  • 在浏览器中运行(Blazor WebAssembly) – .NET 运行时本身通过 WebAssembly 在浏览器中运行。是的,实际编译后的 .NET 代码在浏览器里运行。
  • 两者兼顾(Blazor United/.NET 8+) – 按组件选择渲染模式。服务器端用于首屏加载速度,WebAssembly 用于离线能力。两全其美。
// 一个 Blazor 组件。是的,这就是 UI 中的 C#。
@page "/counter"

<h2>Counter</h2>

<p>Current count: @currentCount</p>

<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

就是这么简单。没有 webpack。没有 Babel。没有成百上千的配置文件。只有可以编译并运行的 C#。

对 React 的质疑

React 本身没问题。它开创了基于组件的 UI,Virtual DOM 也相当聪明。Facebook 在用,而且看起来还不错。

然而,在多年构建生产级 React 应用后,我开始注意到一些让我怀疑人生的模式:

  • 生态系统不断变化 – 每年都会出现一种“正确的”做法。
年份当下流行的状态管理
2016Redux(显而易见)
2018MobX(Redux 太冗长!)
2020Context API(谁还需要库?)
2021Zustand(Context 不够扩展!)
2022Jotai、Recoil、Valtio…
2024Server Components(状态是谎言?)
  • 工具过载 – 启动一个新的 React 项目意味着在编写任何业务代码之前,需要在数十种打包工具、状态管理库、样式方案、数据获取工具、表单库以及元框架之间做选择。

  • TypeScript 的局限 – TypeScript 只是对动态类型语言的临时补丁。类型仅在编译时提供建议,运行时验证仍需手动完成。

// TypeScript:类型其实只是建议
const user: User = JSON.parse(response); // 没有运行时验证!
// 而在 C# 中:
var user = JsonSerializer.Deserialize(response); // 实际的反序列化并进行类型检查
  • node_modules 的安全隐患 – 庞大的依赖树和志愿维护者模式让 npm 生态容易受到供应链攻击。

npm 灾难精选

事件年份影响
left‑pad2016一位开发者撤下了一个 11 行的包。Babel、React 以及成千上万的项目瞬间崩溃。
event‑stream2018“好心”新维护者注入恶意代码,2.5 个月未被发现,目标是比特币钱包。
ua‑parser‑js2021每周 800 万次下载。被劫持后会安装加密矿工和密码窃取器。
everything2024一个“玩笑”包依赖了所有 npm 包,安装它的任何人都会被 DoS。
Shai‑Hulud2025超过 26 亿次每周下载受影响。AI 辅助攻击,带有数据破坏载荷。

为何屡屡发生

  • 巨大的依赖树 – 一个典型的 React 应用拥有数百个传递依赖,每一个都是攻击面。
  • 志愿维护者 – 关键基础设施往往由无偿个人维护,容易被钓鱼或社会工程攻击。
  • 缺乏构建时验证 – npm 只会安装 package.json 中声明的内容,缺少编译时安全检查。
  • 微小包的泛滥 – 生态系统把依赖微小工具(is‑odd?is‑even?)视为常态,累计形成巨大的攻击面。

一个“简单”React 项目的真实 npm 审计结果:

found 47 vulnerabilities (12 moderate, 28 high, 7 critical)

代码对比:React vs Blazor

React(使用 hooks)

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h2>Counter</h2>
      <p>Current count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

Blazor

@page "/counter"

<h2>Counter</h2>

<p>Current count: @count</p>

<button @onclick="() => count++">Click me</button>

@code {
    private int count = 0;
}

两个示例在行数上相似,但 Blazor 版本没有 import、没有 useState hook,也不需要单独的 setter——只用一个普通变量和自增即可。

为什么 Blazor 适合我

  • 零 npm audit 噩梦dotnet list package --vulnerable 通常返回零结果。
  • 签名包 – NuGet 包可以进行加密签名。
  • 精选生态 – 包的总量更少,但平均质量更高。
  • 微软背书 – 核心库由万亿美元公司维护,而非个人开发者。
  • 编译时安全 – C# 编译器在运行前捕获大量问题。
  • 更小的依赖图 – .NET 完整的标准库降低了对外部包的需求。

Blazor 的演进:.NET 8、9、10

  • .NET 8 引入 Blazor United,允许按组件选择渲染模式(Server vs WebAssembly)。
  • .NET 9 增强了 Hot Reload,加速 UI 迭代。
  • .NET 10(预览)承诺与 MAUI 更紧密的集成以及 WebAssembly 的 类原生性能

React 仍然有价值的场景

  • 需要 庞大的现有 JavaScript 生态尚未移植到 Blazor 的第三方 React 组件 的项目。
  • 团队拥有深厚的 JavaScript 专业技能,而 C# 经验有限。
  • 必须 仅客户端渲染,且在浏览器中运行 .NET 运行时的开销不可接受的情况。

开始使用 Blazor

  1. 安装 .NET SDK(≥ 8.0)。

  2. 创建新项目:

    dotnet new blazorwasm -o MyBlazorApp
  3. 运行应用:

    cd MyBlazorApp
    dotnet run
  4. 在浏览器打开 https://localhost:5001 并查看默认模板。

  5. 通过创建 .razor 文件(例如 Counter.razor)添加新页面,遵循前面展示的组件模式。

FAQ:常见疑问解答

问:我需要学习 Razor 语法吗?
答:是的,但它是 HTML 与 C# 代码块的自然扩展。对熟悉 C# 的人来说学习曲线很平缓。

问:性能如何比较?
答:Blazor WebAssembly 的启动稍慢于纯 JS 包,但加载完成后运行时性能相当。Blazor Server 在客户端负载极小,几乎实现即时 UI 更新。

问:我能使用现有的 JavaScript 库吗?
答:完全可以。Blazor 提供 JavaScript 互操作(IJSRuntime),在需要时调用任意 JS 库。

问:SEO 怎么办?
答:服务器端渲染(Blazor Server 或预渲染的 WebAssembly)会向爬虫返回完整的 HTML,提升 SEO 表现。

结语

从 React 转向 Blazor 为我带来了单语言栈,极大降低了依赖相关的安全风险,并简化了开发工作流。React 仍是强大的工具,尤其在你被 JavaScript‑中心生态锁定时。但对于追求更紧密集成、编译时安全以及更可预测依赖图的 .NET 开发者而言,Blazor 是一个极具吸引力的替代方案。

Back to Blog

相关文章

阅读更多 »

Reatom:随你成长的状态管理

碎片化问题 现代前端开发有一个常见的模式: - 从简单的 useState hook 开始 - 需要共享状态?添加 Context - Context re‑...