深度

AI 效率下,浅谈现在的 UI 工程

Web 跨端是 AI 之前的好答卷。现在写代码便宜了,验证还没有,GPU UI 和每端直接生成原生都有了机会。我们实测了 10 个框架。

原创未经许可,不得以任何形式转载

三个窗口分别代表 Web、GPU 自绘和原生,连线汇聚后通向一个红色的验证标记

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 张。

500 张蓝紫色圆角卡片相互重叠,带渐变和阴影
图 1动效压测场景:500 张带渐变和阴影的卡片。Electron / macOS,固定在起始位置的实测程序截图。

Windows

表 1Windows 实测,5 轮中位数。帧为 p95 显示间隔(ms),8.3 即满 120Hz。CPU 以一个逻辑核为 100%。内存为 private commit(MiB)。
框架列表帧动效帧流式 CPU编辑 CPU动效 CPU动效内存
WPF(原生)8.668473%13%49%2,425
Electron8.810831%92%138%947
Tauri无效9254%105%148%913
GPUI8.616.724%4%22%142
MyGo8.48.611%6%33%115
egui8.88.512%20%49%388
iced8.98.520%3%25%215
Slint8.58.527%99%67%61
Flutter8.48022%105%91%4,934
Compose8.816034%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

表 2Mac 实测,5 轮中位数。CPU 以一个逻辑核为 100%;内存为 phys_footprint(MiB)。测试时机器非空闲,不提供跨框架可比的帧率。
框架流式 CPU编辑 CPU动效 CPU列表内存动效内存
SwiftUI87.5%8.9%99.1%4037
Electron16.1%62.0%102.2%536698
Tauri42.1%86.9%78.7%753555
GPUI22.5%2.9%17.0%341335
MyGo8.2%2.8%16.3%368371
egui8.6%7.2%20.4%803839
iced18.2%7.5%15.0%489491
Slint18.4%52.1%26.7%423416
Flutter18.3%101.9%237.4%468994
Compose31.3%105.1%107.5%7101,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 的设计页和共用这套实现的静止场景在修正模糊后重新测量。

表 3测试环境。两台硬件、窗口和内存口径都不同,所以只在同一平台内比较,不比较跨平台的绝对值。
项目MacWindows
机器Apple M4 Max,16 核,64 GBThinkPad T14 Gen6,Core Ultra 7 255H,Arc 140T 核显,32 GB
系统macOS 26.4Windows 11 Pro 10.0.26300
显示Studio Display,60Hz,2x2880×1800,120Hz,200%
窗口1440×900 逻辑像素1280×720 逻辑像素,设计页 1440×900 无边框
内存指标phys_footprintprivate commit(已提交私有内存,不等于物理占用)
帧指标应用回调,各框架含义不同,不用于比较PresentMon 2.6.0 显示间隔,外部测量
机器状态非空闲,测试时有其他开发任务无其他用户操作
表 4受测框架与版本。渲染路径来自运行时日志或框架 API 的实际返回;“未核验”表示这次没有取得运行时证据。
框架版本Mac 渲染路径Windows 渲染路径
SwiftUI / WPFmacOS 26.4 SDK / .NET Framework 4.8.1系统合成WPF 默认 D3D9 管线
Electron45.2.2未核验Chromium,ANGLE D3D11
Tauri2.12.5WKWebViewWebView2 156,ANGLE D3D11
GPUIZed c4273271Metal,默认配置未核验
MyGo86ec3b30未核验未核验
eguieframe 0.37.0MetalVulkan
iced0.14.0MetalVulkan
Slint1.18.1FemtoVG,OpenGLFemtoVG,OpenGL ES
Flutter3.47.9Impeller,MetalImpeller,ANGLE D3D11
Compose1.12.2Skiko,MetalSkiko,D3D12
表 5测试场景。场景由定时器在应用内驱动,无人工操作,测试数据由固定种子生成。
场景工作内容
静止显示设计页后不动,测空闲成本
列表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% 以上。

表 6Windows CPU,单位 %。
框架静止列表流式编辑动效
WPF2.637.272.713.549.3
Electron6.142.830.692.1137.8
Tauri31.658.253.7104.9147.8
GPUI1.510.624.33.621.5
MyGo0.017.910.66.332.8
egui0.315.912.219.648.9
iced0.321.320.23.024.5
Slint0.362.726.999.166.8
Flutter0.631.221.8104.690.6
Compose0.535.934.4106.4101.8
表 7Windows 内存,private commit,单位 MiB。
框架静止列表流式编辑动效
WPF1571932502062,425
Electron280397392556947
Tauri260313346536913
GPUI135142160138142
MyGo132135133132115
egui379386396460388
iced212224274321215
Slint79877220261
Flutter6363963746674,934
Compose4215445743,3722,422
表 8Windows 显示间隔,单位 ms,120Hz 下 8.33 为满帧。轮数是有效帧数据的轮数。
框架列表 p95列表 p99轮数动效 p95动效 p99轮数
WPF8.68.75684.3719.35
Electron8.88.94108.3115.92
Tauri——091.7100.05
GPUI8.68.8516.725.15
MyGo8.48.758.616.75
egui8.88.958.58.75
iced8.98.958.58.65
Slint8.58.858.58.75
Flutter8.48.6580.588.65
Compose8.88.95160.3211.85
表 9Mac CPU,单位 %。机器非空闲。
框架静止列表流式编辑动效
SwiftUI1.016.987.58.999.1
Electron2.516.716.162.0102.2
Tauri6.332.042.186.978.7
GPUI0.49.722.52.917.0
MyGo0.113.28.22.816.3
egui0.19.08.67.220.4
iced0.124.218.27.515.0
Slint0.113.118.452.126.7
Flutter0.211.018.3101.9237.4
Compose0.423.331.3105.1107.5
表 10Mac 内存,phys_footprint,单位 MiB。
框架静止列表流式编辑动效
SwiftUI324013629337
Electron205536567707698
Tauri101753601570555
GPUI74341358320335
MyGo75368361356371
egui414803817862839
iced75489541598491
Slint151423386434416
Flutter156468455663994
Compose3507107091,4261,295
表 11启动是从拉起进程到首帧回调(ms),不是冷缓存首屏。体积是分发目录(MB),不含系统 WebView 和 .NET。
框架Mac 启动Windows 启动Mac 体积Windows 体积
原生(SwiftUI / WPF)2284493.0<0.1
Electron295818267.0376.4
Tauri56562212.511.2
GPUI25527711.913.4
MyGo74212613.111.5
egui30927717.417.4
iced25759014.414.2
Slint26127218.517.0
Flutter2441,04343.930.0
Compose5501,074123.1113.8

设计还原

背景模糊一项要柔化窗口内指定面板的彩条。Compose 1.12.2 给彩条层加上 24 dp 的 Modifier.blur 后,Mac 和 Windows 的原生窗口截图都出现了柔化过渡。SwiftUI 的实现同样先模糊已知的彩条层,再叠加半透明白色。两种写法的验证范围都限于这层已知内容。Compose Desktop API

十个框架的彩条面板对比。Compose、SwiftUI、Electron、Tauri、MyGo 和 Flutter 的条纹过渡柔和,其余四个仍有清晰的色带边缘。
图 2Mac 原生 2× 窗口截图,裁切同一块彩条面板并等比例缩小。

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 在各家都显示成字母。

表 12关键模块的技术选型,来自各框架固定版本的源码和官方文档。
框架布局文字无障碍
GPUITaffymacOS 用 CoreTextAccessKit
egui即时模式布局epaint + harfrustAccessKit
iced自有 flex 布局cosmic-text未找到系统桥接
Slint编译期降低 + 运行时布局ParleyAccessKit
FlutterRenderBox 约束SkParagraphSemantics 树桥接
ComposeMeasurePolicySkiko 的 SkParagraphSemantics,Windows 依赖 Java Access Bridge
ElectronBlinkChromium 文本管线Chromium 无障碍树
Tauri系统 WebView系统 WebView经 WebView 暴露
SwiftUIStack / LayoutTextKit,Core Text系统内建

布局趋同,分歧最大的是文字。iced 在 macOS 上请求 PingFang 700 时,拉丁字母回退到了 Menlo Bold。

局限:

  • 每个平台只有一台机器,动效结果在 Intel 核显上得到,未必适用独显。
  • Mac 测试时机器非空闲,帧数据只有应用回调,不做跨框架比较。
  • 各家阴影的 blur 语义不同,egui、iced、GPUI 是近似实现;编辑控件也不等价,GPUI 用的是改写的示例编辑器。
  • CPU 和内存表只统计应用及纳入的辅助进程,未按窗口分摊 WindowServer 和驱动成本;系统共享资源的复用收益也未量化,不能用这些表给整机渲染成本排名。
  • 输入法候选窗、Mac 无障碍树和功耗没有测出有效结果。
U

ui.surf 编辑部

ui.surf 编辑部 · 1 篇