AI 效率下,浅谈现在的 UI 工程
Web 跨端是 AI 之前的好答卷。现在写代码便宜了,验证还没有,GPU UI 和每端直接生成原生都有了机会。我们实测了 10 个框架。
原创未经许可,不得以任何形式转载

2025 年 12 月 12 日,Zed 的工程师 mikayla-maki 关掉了一个 PR。那个 PR 想给 GPUI 加自定义 shader。回复很客气,先谢过贡献,然后说:“we’re shifting focus to core product work at Zed, and without a Zed use case, I can’t validate this code”,句尾还带了个笑脸。
GPUI 是 Zed 自己写的 GPU 界面框架,谈 Electron 的替代品时,常有人提到它。不到四个月前,Zed 刚宣布拿了红杉领投的 3200 万美元,累计融资过了 4200 万。
九个多月后,2026 年 9 月 26 日,开发者 egoist 建了一个仓库,叫 MyGo。39 天以后,这个仓库有 1,042 个提交,其中 890 个带着 Claude 的署名。
Claude 出自 Anthropic。Anthropic 自己的桌面应用,用的是 Electron。
这三件事摆在一起,有点不对劲。我们在两台机器上实测了 10 个框架,想看看这条赛道走到了哪一步。
01评测背景
Electron 仍被 Claude、Codex 等桌面应用采用:Web 生态成熟,一份代码能跨端,模型也熟悉。AI 降低了开发成本,但多平台兼容与维护仍要投入。
GPU 自绘提供了另一条路,但 GPUI 仍优先服务 Zed,跨平台渲染和控件生态需要长期积累。MyGo 展示了 AI 与现成组件如何加快起步,生产成熟度和长期维护能力仍待验证。
Flutter、Compose、Slint、egui、iced 等框架各有取舍。我们选了 10 个框架,在相同场景下实测流畅度、CPU、内存与设计还原,看看这些路线的实际代价。
02我们在本地测了一遍
我们在 Apple M4 Max 和 ThinkPad T14 Gen6 上,用同一份场景测试了 10 个框架。两端都测 CPU 和内存;Windows 另有 PresentMon 的外部帧测量。Mac 的帧回调口径不一,不用于跨框架比较。硬件和内存指标也不同,下面只在各自平台内比较。
动效是一个密集场景:500 张 96×64 逻辑像素的卡片,排成 25 列并相互重叠,每张带圆角 12、135° 渐变和 blur 16、向下偏移 4 的阴影。所有卡片同时按帧更新位置,绕各自中心做半径 12、周期 4 秒的圆周运动。每轮持续 30 秒,跑 5 轮取中位数。
主要看大量带效果的元素持续移动时,框架更新界面、组织绘制和提交渲染的 CPU 成本,以及能否稳定出帧。CPU 是整个应用进程树的占用,不是 GPU 利用率,也没有拆分各阶段耗时;要结合帧间隔看,少出帧也可能让 CPU 更低。500 是场景中的卡片数,遮挡和窗口裁切意味着并非每帧都完整绘制 500 张。
Windows
| 框架 | 列表帧 | 动效帧 | 流式 CPU | 编辑 CPU | 动效 CPU | 动效内存 |
|---|---|---|---|---|---|---|
| WPF(原生) | 8.6 | 684 | 73% | 13% | 49% | 2,425 |
| Electron | 8.8 | 108 | 31% | 92% | 138% | 947 |
| Tauri | 无效 | 92 | 54% | 105% | 148% | 913 |
| GPUI | 8.6 | 16.7 | 24% | 4% | 22% | 142 |
| MyGo | 8.4 | 8.6 | 11% | 6% | 33% | 115 |
| egui | 8.8 | 8.5 | 12% | 20% | 49% | 388 |
| iced | 8.9 | 8.5 | 20% | 3% | 25% | 215 |
| Slint | 8.5 | 8.5 | 27% | 99% | 67% | 61 |
| Flutter | 8.4 | 80 | 22% | 105% | 91% | 4,934 |
| Compose | 8.8 | 160 | 34% | 106% | 102% | 2,422 |
列表滚动大家都跟得上。差距出在动效:500 张带阴影和渐变的卡片,Rust 和 Go 的自绘框架基本守住了 120Hz,Flutter、Electron、Tauri、Compose 的帧间隔到了 80 到 160ms。WPF 的 684ms 来自 500 个独立阴影效果,关掉就回到 8.3ms,算不上通病。
文本编辑是另一道坎。5,000 行文档每秒插入 10 个字符,Flutter、Compose、Slint 都打满了一个核,Flutter 在 Windows 上还掉了三成的输入。
Mac
| 框架 | 流式 CPU | 编辑 CPU | 动效 CPU | 列表内存 | 动效内存 |
|---|---|---|---|---|---|
| SwiftUI | 87.5% | 8.9% | 99.1% | 40 | 37 |
| Electron | 16.1% | 62.0% | 102.2% | 536 | 698 |
| Tauri | 42.1% | 86.9% | 78.7% | 753 | 555 |
| GPUI | 22.5% | 2.9% | 17.0% | 341 | 335 |
| MyGo | 8.2% | 2.8% | 16.3% | 368 | 371 |
| egui | 8.6% | 7.2% | 20.4% | 803 | 839 |
| iced | 18.2% | 7.5% | 15.0% | 489 | 491 |
| Slint | 18.4% | 52.1% | 26.7% | 423 | 416 |
| Flutter | 18.3% | 101.9% | 237.4% | 468 | 994 |
| Compose | 31.3% | 105.1% | 107.5% | 710 | 1,295 |
Mac 上,GPUI、MyGo、egui、iced 的动效 CPU 约为 15%–20%,Flutter 为 237%,Electron 和 Compose 约 100%。文本编辑时,Flutter 和 Compose 仍接近一个核,Slint 则为 52%,低于它在 Windows 上的 99%。
列表场景中,SwiftUI 约 40 MiB、GPUI 约 340 MiB、egui 约 800 MiB,首先反映的是应用进程的内存足迹。原生 UI 可以利用系统的进程外渲染服务:Apple 明确说明 AppKit 通常在进程外渲染图层树,因此部分绘制与合成工作并不发生在应用进程里。自绘框架也要经过系统合成,但两条路径在应用与系统之间如何分工,不能只看应用进程判断。M 系列的统一内存让 CPU 和 GPU 共用物理内存,并不意味着所有相关成本都会计入应用的 phys_footprint。
本次 SwiftUI 列表和动效各 5 轮短时 GPU trace 中,未观测到应用 PID 的 GPU 执行事件,同期 WindowServer 有 GPU 活动;这不代表 SwiftUI 不用 GPU,也不能把整个桌面的活动都算给它。WindowServer 内存基线还存在约 205 MiB 的波动,快照未见大额共享对象,也不足以排除系统已有资源的复用。因此,这组数据只能说明 SwiftUI 的应用进程占用较低,不能据此断言完整渲染成本更低,也不能把差额全部归为系统代付。
这些数字只代表这两台机器、这些版本和我们写的测试程序。方法和完整数据在第 05 节。
03从来都不是极限N选1
编辑器、开发工具、业务应用,对文本输入、动效、内存、跨端交付和控件生态的要求不一样。大家都有各自的场景需求,选型要看这些取舍能不能接受。
不少框架现在也在做保留、缓存和局部更新,减少重复的布局与绘制。GPUI 是即时与保留混合的设计。采用哪种模式、哪些工作能复用,和一帧能画多快,是不同层面的问题。
动效上,MyGo、iced、GPUI、Slint、egui 都跟得上,CPU 占用也低。Slint 内存最小,egui 内存偏高,GPUI 的编辑控件要自己补。MyGo 目前主要是作者自己的应用在用,并没有大量生产规模验证。
Flutter、Electron、Compose 在这次动效压测中的帧间隔和资源占用也不理想。Tauri 的包只有 11 MB,运行时内存和 Electron 差不多。
04卡点在验证
我们现在觉得,比渲染更要紧的是验证。
写代码便宜了,确认代码写对了还是要花时间。Stack Overflow 2025 年的开发者调查里,66% 的人遇到过 AI 给的方案 “almost right, but not quite”,45.2% 说调试 AI 写的代码更费时间。Sonar 今年 1 月公布的调查里,96% 的开发者不完全相信 AI 生成的代码功能正确,只有 48% 说提交前总会检查。Sonar 是卖代码检查工具的,这个数字要打点折扣,但和前一份对得上。
Slint 和 egui 那两次发布动静不大,我们觉得比渲染上的进展要紧。agent 能注入输入、能截图,才能改一下,看一眼,再改。以前验一个界面,要有人坐在机器前一个个点,现在这件事开始能交给机器。
眼下有三种做法。Web 跨端手里的东西最多。GPU 自绘不用带着一个浏览器走,门槛也比以前低了。每端做原生是最老的办法,以前只有大公司养得起几支团队,现在的难处是 Breunig 说的三倍 bug 和支持面。如果验证的成本降下来,质量上去,每个平台直接生成一份原生应用,也可能行得通。
我们也在做自己的 GPU UI 尝试,差异是把大量 Web 开发的 DX 带进来:类 JSX 的组件,类 CSS 的样式,flexbox 布局,响应式状态,浏览器那样的 DevTools,最后编译成原生代码。它还在早期。
哪种答案会赢,我们不知道,也可能几种长期并存。开头那三件事,到今天都没变。那个 PR 还关着,MyGo 还在涨,Claude 的桌面端还是 Electron。这个时代,是非常有意思的。
05实验报告
测试于 2026 年 11 月 4 日至 6 日进行。同一份场景在每个框架上各实现一遍,用官方推荐写法和默认配置,Release 构建。Compose 的设计页和共用这套实现的静止场景在修正模糊后重新测量。
| 项目 | Mac | Windows |
|---|---|---|
| 机器 | Apple M4 Max,16 核,64 GB | ThinkPad T14 Gen6,Core Ultra 7 255H,Arc 140T 核显,32 GB |
| 系统 | macOS 26.4 | Windows 11 Pro 10.0.26300 |
| 显示 | Studio Display,60Hz,2x | 2880×1800,120Hz,200% |
| 窗口 | 1440×900 逻辑像素 | 1280×720 逻辑像素,设计页 1440×900 无边框 |
| 内存指标 | phys_footprint | private commit(已提交私有内存,不等于物理占用) |
| 帧指标 | 应用回调,各框架含义不同,不用于比较 | PresentMon 2.6.0 显示间隔,外部测量 |
| 机器状态 | 非空闲,测试时有其他开发任务 | 无其他用户操作 |
| 框架 | 版本 | Mac 渲染路径 | Windows 渲染路径 |
|---|---|---|---|
| SwiftUI / WPF | macOS 26.4 SDK / .NET Framework 4.8.1 | 系统合成 | WPF 默认 D3D9 管线 |
| Electron | 45.2.2 | 未核验 | Chromium,ANGLE D3D11 |
| Tauri | 2.12.5 | WKWebView | WebView2 156,ANGLE D3D11 |
| GPUI | Zed c4273271 | Metal,默认配置 | 未核验 |
| MyGo | 86ec3b30 | 未核验 | 未核验 |
| egui | eframe 0.37.0 | Metal | Vulkan |
| iced | 0.14.0 | Metal | Vulkan |
| Slint | 1.18.1 | FemtoVG,OpenGL | FemtoVG,OpenGL ES |
| Flutter | 3.47.9 | Impeller,Metal | Impeller,ANGLE D3D11 |
| Compose | 1.12.2 | Skiko,Metal | Skiko,D3D12 |
| 场景 | 工作内容 |
|---|---|
| 静止 | 显示设计页后不动,测空闲成本 |
| 列表 | 10,000 行虚拟化列表,行高 64,以 2,000 px/s 匀速滚动 |
| 流式 | 载入 200 条历史消息,再按每秒 40 词追加到最后一条,始终贴底 |
| 编辑 | 5,000 行文档,每秒在光标处插入 10 个字符 |
| 动效 | 500 张 96×64 卡片,圆角 12,渐变加阴影,按统一公式做圆周运动 |
| 设计页 | 11 项设计规格:字体、阴影、细线、渐变、P3、背景模糊、圆角、emoji、OpenType、中英混排 |
每个框架每个场景跑 5 轮,每轮 30 秒,串行执行,顺序打乱,下表都是中位数。5 轮之间的极差中位数约 3%,九成在 24% 以内。列表和动效是统一规格后重测的,所以不同列不是同一时段采集的。CPU 以一个逻辑核为 100%。多进程应用计入所有子进程,Mac 的 Tauri 还计入系统为它启动的 WebKit 进程。Windows 的帧数据只用能唯一归到一个 swapchain 且零丢失的轮次。
流式和编辑都核对了实际交付量:Windows 上 Flutter 的编辑只完成 68%,其余都在 99% 以上。
| 框架 | 静止 | 列表 | 流式 | 编辑 | 动效 |
|---|---|---|---|---|---|
| WPF | 2.6 | 37.2 | 72.7 | 13.5 | 49.3 |
| Electron | 6.1 | 42.8 | 30.6 | 92.1 | 137.8 |
| Tauri | 31.6 | 58.2 | 53.7 | 104.9 | 147.8 |
| GPUI | 1.5 | 10.6 | 24.3 | 3.6 | 21.5 |
| MyGo | 0.0 | 17.9 | 10.6 | 6.3 | 32.8 |
| egui | 0.3 | 15.9 | 12.2 | 19.6 | 48.9 |
| iced | 0.3 | 21.3 | 20.2 | 3.0 | 24.5 |
| Slint | 0.3 | 62.7 | 26.9 | 99.1 | 66.8 |
| Flutter | 0.6 | 31.2 | 21.8 | 104.6 | 90.6 |
| Compose | 0.5 | 35.9 | 34.4 | 106.4 | 101.8 |
| 框架 | 静止 | 列表 | 流式 | 编辑 | 动效 |
|---|---|---|---|---|---|
| WPF | 157 | 193 | 250 | 206 | 2,425 |
| Electron | 280 | 397 | 392 | 556 | 947 |
| Tauri | 260 | 313 | 346 | 536 | 913 |
| GPUI | 135 | 142 | 160 | 138 | 142 |
| MyGo | 132 | 135 | 133 | 132 | 115 |
| egui | 379 | 386 | 396 | 460 | 388 |
| iced | 212 | 224 | 274 | 321 | 215 |
| Slint | 79 | 87 | 72 | 202 | 61 |
| Flutter | 636 | 396 | 374 | 667 | 4,934 |
| Compose | 421 | 544 | 574 | 3,372 | 2,422 |
| 框架 | 列表 p95 | 列表 p99 | 轮数 | 动效 p95 | 动效 p99 | 轮数 |
|---|---|---|---|---|---|---|
| WPF | 8.6 | 8.7 | 5 | 684.3 | 719.3 | 5 |
| Electron | 8.8 | 8.9 | 4 | 108.3 | 115.9 | 2 |
| Tauri | — | — | 0 | 91.7 | 100.0 | 5 |
| GPUI | 8.6 | 8.8 | 5 | 16.7 | 25.1 | 5 |
| MyGo | 8.4 | 8.7 | 5 | 8.6 | 16.7 | 5 |
| egui | 8.8 | 8.9 | 5 | 8.5 | 8.7 | 5 |
| iced | 8.9 | 8.9 | 5 | 8.5 | 8.6 | 5 |
| Slint | 8.5 | 8.8 | 5 | 8.5 | 8.7 | 5 |
| Flutter | 8.4 | 8.6 | 5 | 80.5 | 88.6 | 5 |
| Compose | 8.8 | 8.9 | 5 | 160.3 | 211.8 | 5 |
| 框架 | 静止 | 列表 | 流式 | 编辑 | 动效 |
|---|---|---|---|---|---|
| SwiftUI | 1.0 | 16.9 | 87.5 | 8.9 | 99.1 |
| Electron | 2.5 | 16.7 | 16.1 | 62.0 | 102.2 |
| Tauri | 6.3 | 32.0 | 42.1 | 86.9 | 78.7 |
| GPUI | 0.4 | 9.7 | 22.5 | 2.9 | 17.0 |
| MyGo | 0.1 | 13.2 | 8.2 | 2.8 | 16.3 |
| egui | 0.1 | 9.0 | 8.6 | 7.2 | 20.4 |
| iced | 0.1 | 24.2 | 18.2 | 7.5 | 15.0 |
| Slint | 0.1 | 13.1 | 18.4 | 52.1 | 26.7 |
| Flutter | 0.2 | 11.0 | 18.3 | 101.9 | 237.4 |
| Compose | 0.4 | 23.3 | 31.3 | 105.1 | 107.5 |
| 框架 | 静止 | 列表 | 流式 | 编辑 | 动效 |
|---|---|---|---|---|---|
| SwiftUI | 32 | 40 | 136 | 293 | 37 |
| Electron | 205 | 536 | 567 | 707 | 698 |
| Tauri | 101 | 753 | 601 | 570 | 555 |
| GPUI | 74 | 341 | 358 | 320 | 335 |
| MyGo | 75 | 368 | 361 | 356 | 371 |
| egui | 414 | 803 | 817 | 862 | 839 |
| iced | 75 | 489 | 541 | 598 | 491 |
| Slint | 151 | 423 | 386 | 434 | 416 |
| Flutter | 156 | 468 | 455 | 663 | 994 |
| Compose | 350 | 710 | 709 | 1,426 | 1,295 |
| 框架 | Mac 启动 | Windows 启动 | Mac 体积 | Windows 体积 |
|---|---|---|---|---|
| 原生(SwiftUI / WPF) | 228 | 449 | 3.0 | <0.1 |
| Electron | 295 | 818 | 267.0 | 376.4 |
| Tauri | 565 | 622 | 12.5 | 11.2 |
| GPUI | 255 | 277 | 11.9 | 13.4 |
| MyGo | 742 | 126 | 13.1 | 11.5 |
| egui | 309 | 277 | 17.4 | 17.4 |
| iced | 257 | 590 | 14.4 | 14.2 |
| Slint | 261 | 272 | 18.5 | 17.0 |
| Flutter | 244 | 1,043 | 43.9 | 30.0 |
| Compose | 550 | 1,074 | 123.1 | 113.8 |
设计还原
背景模糊一项要柔化窗口内指定面板的彩条。Compose 1.12.2 给彩条层加上 24 dp 的 Modifier.blur 后,Mac 和 Windows 的原生窗口截图都出现了柔化过渡。SwiftUI 的实现同样先模糊已知的彩条层,再叠加半透明白色。两种写法的验证范围都限于这层已知内容。Compose Desktop API
GPUI、iced、egui 和 Slint 的受测实现只在彩条上叠了半透明层,复测中仍能看到清晰的色带边缘。GPUI 的 Blurred 和 iced 的 window::Settings::blur 作用于窗口背后的内容。受测版本的内置绘制接口中未找到局部背景模糊。iced 可以用自定义渲染绘制局部效果,egui 可通过 PaintCallback 接入渲染后端。GPUI · iced 窗口设置 · egui 绘制回调
Slint 的受测组合是 1.18.1 和 FemtoVG,该版本未提供元素的 backdrop-blur 属性。后续上游已为 Skia 渲染器加入此属性,本次截图对应 1.18.1 的 FemtoVG 路径。Slint 上游记录
设计页共 11 项。Mac 上 GPUI、egui、iced、Slint、Compose 的 P3 色块在本次输出中未还原。Windows 的截图没有色彩配置,P3 不作判定,旗帜 emoji 在各家都显示成字母。
| 框架 | 布局 | 文字 | 无障碍 |
|---|---|---|---|
| GPUI | Taffy | macOS 用 CoreText | AccessKit |
| egui | 即时模式布局 | epaint + harfrust | AccessKit |
| iced | 自有 flex 布局 | cosmic-text | 未找到系统桥接 |
| Slint | 编译期降低 + 运行时布局 | Parley | AccessKit |
| Flutter | RenderBox 约束 | SkParagraph | Semantics 树桥接 |
| Compose | MeasurePolicy | Skiko 的 SkParagraph | Semantics,Windows 依赖 Java Access Bridge |
| Electron | Blink | Chromium 文本管线 | Chromium 无障碍树 |
| Tauri | 系统 WebView | 系统 WebView | 经 WebView 暴露 |
| SwiftUI | Stack / Layout | TextKit,Core Text | 系统内建 |
布局趋同,分歧最大的是文字。iced 在 macOS 上请求 PingFang 700 时,拉丁字母回退到了 Menlo Bold。
局限:
- 每个平台只有一台机器,动效结果在 Intel 核显上得到,未必适用独显。
- Mac 测试时机器非空闲,帧数据只有应用回调,不做跨框架比较。
- 各家阴影的 blur 语义不同,egui、iced、GPUI 是近似实现;编辑控件也不等价,GPUI 用的是改写的示例编辑器。
- CPU 和内存表只统计应用及纳入的辅助进程,未按窗口分摊 WindowServer 和驱动成本;系统共享资源的复用收益也未量化,不能用这些表给整机渲染成本排名。
- 输入法候选窗、Mac 无障碍树和功耗没有测出有效结果。

