---
url: https://nsh.dev/zh-CN/docs/comparison
description: "应用显示发布之后才到来的界面有哪些做法——WebView、服务端驱动 UI、小程序容器、热更新——它们与 NSH 的比较，以及 NSH 与 React Native、Flutter、Electron、Tauri 等跨平台框架的比较。"
---

# 方案对比

应用想要显示安装包里没有的界面——由模型生成的回答、来自合作方或其他团队的功能、无需发版就能变化的页面——无论在手机还是桌面上，都已有几种成熟的做法。它们的区别在于：界面由什么绘制，下发的代码能做什么，以及宿主应用要为承载它们做多大的改动。本页先把它们与 NSH 放在一起比较，再把 NSH 与用来编写完整应用的跨平台框架做比较。

## 几种做法

| | 由什么绘制 | 能表达什么 | 约束方式 | 适合生成式界面吗 | 宿主应用的代价 |
|---|---|---|---|---|---|
| **WebView（H5）** | 浏览器引擎 | HTML、CSS、JS 能做的一切 | 同源策略；原生能力通过手写的桥接暴露 | 模型擅长写 HTML；但结果看起来、用起来都是网页 | 每个视图一个浏览器引擎；还要维护桥接 |
| **服务端驱动 UI** | 应用自己的原生视图 | 只能组合应用内置的组件和动作，用 JSON 描述 | 完全受限：协议就是边界 | 容易生成，但能表达的很少：协议之外没有本地状态和逻辑 | 每个应用都要为每个组件及其版本实现渲染器 |
| **小程序容器** | 通常是 Web 引擎加一层私有封装 | 平台特有的框架和 API | 容器自己的权限模型 | 私有方言，模型不熟悉 | 体积很大的容器 SDK |
| **跨平台应用的热更新**（例如 React Native 搭配代码推送服务） | 该框架的渲染器 | 整个框架的能力 | 没有约束：更新就是受信任的应用代码 | 这类更新并不是为按请求生成的代码设计的 | 整个应用都得用该框架编写 |
| **NSH** | 平台自己的界面：UIKit、Android 视图、AppKit、GTK 4、用 Direct2D 绘制的 Win32 | 带状态、逻辑、动画和布局的组件；宿主注册的原生视图 | 签名包；每个视图一个虚拟机，限制由宿主设定；能力按视图授予 | 为此而设计：一个 TSX 模块、类型化的 API、无界面验证 | 在现有原生应用里放一个视图、加一个库 |

## NSH 的不同之处

- **平台自己的界面。** 模块由平台的视图组成，文本选区及其菜单、输入法、无障碍和滚动都是系统自己的——这也是 NSH 在 [GPUI Shell](https://nsh.dev/zh-CN/docs.md) 之外存在的原因。
- **不止一套协议。** 服务端驱动 UI 只能重新组合应用已有的东西；NSH 模块有自己的状态、逻辑、动画和布局，模型可以生成应用开发者事先没有预料到的界面。
- **由宿主约束。** 下发的代码是不可信的。NSH 在运行任何代码之前检查签名和吊销列表，为每个视图分配独立的虚拟机并设定内存、调用时长和节点数限制，由宿主决定模块能访问哪些网络主机、网页和系统设置（[沙箱与能力](https://nsh.dev/zh-CN/docs/sandbox-and-capabilities.md)）。
- **嵌入，而不是迁移。** 应用仍然是原生应用，沿用原来的工具链；NSH 只是放在需要显示模块的地方的一个视图（[平台](https://nsh.dev/zh-CN/docs/platforms.md#嵌入原生应用)）。
- **一个模块，所有平台。** 同一个 bundle 运行在 iOS、Android、macOS、Windows 和 Linux 上，每次都使用该平台自己的界面（[平台](https://nsh.dev/zh-CN/docs/platforms.md)）。

## 跨平台框架

NSH 是为原生应用里的模块而设计的，但同样的模块也可以为每个平台打包成完整的应用，所以很自然会拿它和人们用来编写跨平台应用的框架比较。这里比较的是各自如何绘制、运行在哪里，而不是成熟度：这些框架拥有 NSH 所没有的庞大生态。

| | 由什么绘制 | 平台 | 应用代码 | 发布之后下发的代码 |
|---|---|---|---|---|
| **React Native** | iOS 和 Android 上是平台视图；桌面端通过独立项目支持 | iOS、Android；Windows 和 macOS 由主仓库之外的项目支持 | JavaScript 或 TypeScript，搭配 React | 受信任应用代码的热更新 |
| **Flutter** | 自己的引擎绘制每一个像素 | iOS、Android、macOS、Windows、Linux、Web | Dart | 不属于框架本身 |
| **Electron** | 随应用打包的 Chromium | macOS、Windows、Linux | HTML、CSS、JavaScript | 应用加载的网页内容 |
| **Tauri** | 系统的 WebView | macOS、Windows、Linux、iOS、Android | HTML、CSS、JavaScript；原生部分用 Rust | 应用加载的网页内容 |
| **NSH** | 每个平台自己的界面 | iOS、Android、macOS、Windows、Linux | TSX 模块；运行时和组件是 Rust | 签名包，经过校验，每个视图独立沙箱 |

NSH 的不同之处：

- **每个平台用原生界面，而不是一个渲染器走天下。** Flutter 自己绘制一切，Electron 和 Tauri 显示网页；NSH 构建每个平台自己的视图，所以文本选区、输入法、无障碍和系统外观都来自平台本身。
- **嵌在原生应用里的小模块。** 上面这些框架掌管整个应用。NSH 的设计是待在用平台自己的工具编写的应用里，作为众多视图之一，在沙箱里运行应用发布时没有带上的模块。
- **轻量的运行时。** 不需要为每个应用或每个视图带一个浏览器引擎；JavaScript 只运行模块自己的代码，它调用的一切都是原生的 Rust。

## 什么时候其他做法更合适

- 界面本身就是文档或现成的网页：WebView 可以原样显示。
- 页面集合固定且很少，变化的只是内容和顺序：服务端驱动 UI 完全不需要运行时。
- 整个应用本来就是用某个跨平台框架编写的：用它自己的更新机制下发代码即可。
- 你需要庞大的第三方包生态，或者现在就需要一套带桌面控件的桌面 UI 组件：NSH 的组件是移动端组件集。

## 另请参阅

- [简介](https://nsh.dev/zh-CN/docs.md)：NSH 为什么存在、为什么而设计。
- [架构](https://nsh.dev/zh-CN/docs/architecture.md)：NSH 内部各部分在哪里运行。
