DeepSeek-Reasonix 桌面壳迁移性能基线:Wails 与 Electron 的启动、内存与进程树量化对比
【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix
本篇技术指南以 docs/desktop-migration/baseline/README.md 为骨架,完整呈现 DeepSeek-Reasonix 桌面壳(Desktop Shell)从 Wails 迁移到 Electron 过程中留下的量化基线:Wails 冻结版本的启动耗时、进程树 RSS、进程数量与信号响应等指标,以及同一脚本、同一机器上 Electron 开发构建的对照数据。读完本文,你将掌握这套桌面壳资源测量的脚本化方法(desktop-shell-metrics.sh)、各指标的确切定义(ready/healthy/RSS 采样口径),并能对照 Phase F 验收门禁理解 Electron 壳在打包形态下的启动、标签页、泄漏与一小时持续使用表现。
基线背景:为什么冻结一个 Wails 基线
DeepSeek-Reasonix 的桌面客户端原本基于 Wails(WebView2/WebKitGTK),在迁移到 Electron 壳之前,团队先冻结了旧壳的一个构建,用同一套测量脚本采集资源与性能数据,作为后续所有 Electron 构建的对照基准。这套数据的约束条件写得很明确:用scripts/desktop-shell-metrics.sh采集,冻结基线构建为wails build -platform darwin/arm64,运行环境为 Apple silicon、macOS 26.6,共跑 3 次,每次使用全新的一次性数据目录(fresh disposable data home),并设置REASONIX_DEV=1。原始运行数据以 JSON 形式存放在 docs/desktop-migration/baseline/ 目录下(wails-darwin-arm64-run{1,2,3}.json),与本文并排。
测量方法与指标口径
要正确解读基线数字,必须先理解脚本如何定义"启动完成"。从 scripts/desktop-shell-metrics.sh 的源码可以看到完整的测量流程:
- 一次性数据目录:脚本用
mktemp -d创建REASONIX_HOME/REASONIX_STATE_HOME/REASONIX_CACHE_HOME,保证每次运行都是冷启动,且通过REASONIX_DEV=1跳过单实例锁(对应 Electron 壳中REASONIX_DEV跳过 single-instance lock 的行为,见 desktop/electron/README.md)。 ready与healthy两个阶段:脚本以 100 ms 间隔轮询数据目录下**/diagnostics/lifecycle/*.json生命周期诊断文件,ready是 Go 生命周期到达ready阶段,healthy是 React 应用渲染完成且桥接心跳(bridge heartbeat)成功。注意起点是 Gomain开始执行(对 Wails 是reasonix-desktop进程启动),而非进程创建时刻。- 进程树 RSS:脚本用
ps -axo pid=,ppid=,rss=,lstart=,comm=全量快照,递归收集被测进程的后代,再按WebKit、Electron Helper、reasonix-desktop、Reasonix Helper等进程名族把启动后出现的辅助进程并入家族(macOS 上 WebKit XPC 辅助进程会 reparent 到 launchd,必须按名字补抓),求和得到 KiB。因此脚本注释明确警告:只可比对同一脚本的多次运行,不要与不同口径采样的数据比较。 - 采样时机:
healthy之后 2 s、10 s、30 s(可传第 4 个参数覆盖 idle 秒数)。 - SIGTERM 响应:发送
SIGTERM后轮询 10 秒,记录是否在 10 秒内退出,并输出terminatedWithinMs与clean字段。
Wails 冻结基线:三次运行的中位数
以下表格是原文档完整继承的基线中位数(中位数取三次运行):
| Metric | Median of 3 |
|---|---|
Gostartup→ lifecycleready | 332 ms |
Gostartup→ frontendhealthy(React 挂载 + 桥接心跳) | 3692 ms |
| Process-tree RSS, healthy + 2 s | 389 MiB |
| Process-tree RSS, healthy + 10 s | 385 MiB |
| Process-tree RSS, healthy + 30 s | 412 MiB |
| Processes in the tree | 4(com.apple.WebKit.GPU、com.apple.WebKit.Networking、com.apple.WebKit.WebContent、reasonix-desktop) |
| SIGTERM honoured within 10 s | no(Wails 壳忽略 SIGTERM,脚本最终只能 SIGKILL) |
从原始 JSON(如 wails-darwin-arm64-run1.json)可以看出单次运行形态:run 1 的readyMs为 1248 ms、healthyMs为 4563 ms,包含冷数据目录的首次启动开销;run 2、run 3 复用热的 OS 文件缓存。RSS 采样中 run 1 在 healthy+2 s 为约 389 MiB、+10 s 约 380 MiB、+30 s 约 404 MiB,terminatedWithinMs11130 ms 且clean: false——正好印证了"SIGTERM 不被响应、只能强杀"的结论。
该文档同时指出:交互延迟(会话切换、停止反馈、输入)不在此脚本范围内,由 desktop/frontend/bench 下的前端基准单独采集。
同机同脚本的 Electron 对照
Electron 侧使用 desktop/electron/scripts/metrics-launch.sh 启动:该脚本把REASONIX_DESKTOP_SERVICE指向以-X main.version=v0.0.0-electron构建的 Go 服务二进制,然后execElectron 二进制,使被测量的 PID 就是壳本身(这是让desktop-shell-metrics.sh能正确跟踪进程树的必要条件)。Electron 版本为 44.2.0,同样是三次运行、每次全新数据目录。原文档特别提示:起点不同——Electron 的计时从 Electronmain进程启动(含 Chromium 初始化)开始,因此其ready天然晚于从 Gomain计时的 Wails 数字。
原文档完整对照表:
| Metric | Wails (median of 3) | Electron (median of 3) | Delta |
|---|---|---|---|
launch → Go lifecycleready | 332 ms | 448 ms | +116 ms |
launch → frontendhealthy | 3692 ms | 3742 ms | +50 ms |
| Process-tree RSS, healthy + 2 s | 389 MiB | 665 MiB | +276 MiB |
| Process-tree RSS, healthy + 10 s | 385 MiB | 668 MiB | +283 MiB |
| Process-tree RSS, healthy + 30 s | 412 MiB | 697 MiB | +285 MiB |
| Processes in the tree | 4 | 5(Electron、Electron Helper、Electron Helper (Renderer)、reasonix-desktop-service-versioned) | |
| SIGTERM honoured within 10 s | no | yes (247 ms) |
解读要点(均来自原文档原文):
- 固定成本是 Chromium 运行时 + 第二个 renderer 类进程;而"前端达到 healthy"的时间在噪声范围内与 Wails 持平(+50 ms)。
- 未打包的 Electron 壳通过
reasonix://app处理器从frontend/dist加载 UI,与打包构建走同一条路径——这正是 desktop/electron/README.md 所述架构:renderer(reasonix://app)→ preload(window.reasonixDesktop)→ main process → NDJSON JSON-RPC over stdio →reasonix-desktop --host-rpc。 - 2 s 到 30 s 之间的空闲增长两个壳处于同一量级,该增长会在 Phase F 验收运行中以一小时维度重新测量。
打包形态的 Phase F 验收证据
原文档指向的 PHASE_F_ACCEPTANCE.md 记录了打包 macOS 产物(dist/Reasonix-darwin-arm64.zip,候选 SHA650e01e31,zip 191.7 MiB,解包.app489 MB)上的验收运行,对应 docs/DESKTOP_SHELL_MIGRATION.md 中 Phase F 门禁的资源/性能行。三组数字放在一起对比(均为中位数):
| Metric | Wails baseline | Electron dev shell | Electron packaged | Δ vs Wails |
|---|---|---|---|---|
launch → Go lifecycleready | 332 ms | 448 ms | 598 ms | +266 ms |
launch → frontendhealthy | 3692 ms | 3742 ms | 3991 ms | +299 ms |
| Process-tree RSS, healthy + 2 s | 389 MiB | 665 MiB | 672 MiB | +283 MiB |
| Process-tree RSS, healthy + 10 s | 385 MiB | 669 MiB | 673 MiB | +288 MiB |
| Process-tree RSS, healthy + 30 s | 412 MiB | 698 MiB | 660 MiB | +248 MiB |
| Processes in the tree | 4 | 5 | 5(Reasonix、Reasonix Helper ×2(GPU/utility + Renderer)、reasonix-desktop) | +1 |
| SIGTERM honoured | no(需 SIGKILL) | yes (247 ms) | yes (239–252 ms,3/3 干净退出) | improved |
打包形态的额外结论:
- run 1 承担了解包副本的首次启动成本(ready 3901 ms、healthy 7592 ms),run 2–3 为热缓存(ready 595/598 ms、healthy 3945/3991 ms),因此中位数反映热启动。time-to-healthy 比 Wails 多 299 ms——若套用
max(1.2×, +50 ms)(= 4430 ms)的启动门禁仍在范围内;计划对启动/内存的规则是"按测量结果发布,固定开销本身不构成失败"。 - ~+250–290 MiB 的 RSS 增量是 Chromium 运行时固定成本,在 30 s 空闲窗口内保持平坦(除 Wails 自身增长外无额外空闲增长)。
- 浏览器标签页场景(
temporary表面,不同源):空闲 683 MiB/5 进程/1 WebContents → 1 标签 750 MiB/6 进程/2 → 5 标签 1226 MiB/10 进程/6 → 全部关闭后 5 s 沉降回到 673 MiB/5 进程/1,无标签残留。 - 35 次打开/关闭循环(门禁要求 ≥30):WebContents 数量、每 WebContents 监听器总数、活动句柄数全程不动,进程数沉降后回到 5;RSS 在 35 个循环中漂移 +30 MiB(664→694),且增量递减(每 10 个循环 +11/+9/+10)、循环后不再攀升,形态是 renderer/OS 缓存而非每循环泄漏,结论为标签开合无持续泄漏。会话循环(35 ×
NewSession+DeleteSession)中 Go 服务 RSS 69→70 MiB,会话数 0→0——注意这是空白会话的 RPC/轮转路径验证。 - 一小时持续使用(5 个标签保持打开,每 5 分钟一次临时标签开合 + 业务 RPC):WebContents、监听器、句柄数与标签集合整小时恒定,RSS 1271→1323 MiB(+52 MiB,+4%),约第 35 分钟见顶 1381 MiB 后回落——减速、部分被 GC 回收的增长,集中于主窗口 renderer(245→352 MiB),非单调泄漏。Wails 侧无对应一小时数据(基线只覆盖 30 s),按计划以测量值发布。
交互 p95 门禁与未覆盖缺口
迁移计划原要求交互 p95(会话切换、停止反馈、输入延迟)相对 Wails 基线保持在max(1.2 × baseline, baseline + 50 ms)内,但验收文档诚实记录了关键缺口:Wails 交互基线从未记录——基线 README 声称交互延迟由desktop/frontend/bench单独采集,但仓库中不存在任何 Wails 侧数字,且 Wails 在本阶段已被移除,相对门禁无法计算。作为替代,同一机器同日测量了:
- 前端基准(
pnpm test:bench,headless Chromium 中的生产前端,38 轮工具密集与 46 轮 markdown 密集会话):冷打开首帧 p95 20 ms(门禁 100 ms,PASS);冷打开可交互 p95 944/337 ms(门禁 300 ms,FAIL,归因于首次冷打开的运行间方差);会话切换 p95 471/475 ms(门禁 300 ms,FAIL);激活就绪 p95 98/101 ms(PASS);输入事件 p95 24 ms(门禁 200 ms,PASS);长任务 p95 79/86 ms(门禁 50 ms,FAIL p95);100 次切换后保留堆增长 3.5 MiB(门禁 20 MiB,PASS);DOM 节点增长 0.0%(PASS)。由于该 harness 与前端对两个壳完全相同,这些数字不能归因于 Electron 迁移。 - 打包壳内的真实探针(PerformanceObserver + 真实键盘事件,15 次击键预热后):keydown/input p50 24 ms、p95 40 ms、max 72 ms(n=80),与 headless 基准一致;无预热时首次击键需支付一次性 composer 初始化。
明确列出的未测量缺口:停止反馈 p95 与流式/长会话内存(需要配置了模型提供商的运行中 turn,一次性数据目录中没有且无 Go 侧 mock 提供商);带真实内容的会话开合(新 home 中会话为空白,35 循环只证明 RPC/轮转路径);真实壳的会话切换 p95(新 home 项目树为 0 主题,侧边栏切换无法在打包壳内演练,以前端基准数字代替)。
结论与阅读指引
这套基线文档的价值在于:它把"换壳"这种容易停留在定性讨论的工程决策,落实为同一脚本、同一机器、同一采样口径下的可重复量化证据。Wails 在启动计时(从 Gomain起算)和常驻内存上占优,Electron 的代价是 Chromium 运行时固定成本(约 +250–290 MiB 与一个额外进程),但换来的是可靠、快速的 SIGTERM 响应与完整的浏览器表面能力;"前端可交互"时间两者在噪声范围内持平。原始证据链完整可查:Wails 三次运行见 wails-darwin-arm64-run1.json(run 2/3 同目录),Electron 开发构建见electron-darwin-arm64-run{1,2,3}.json,Phase F 各场景证据见electron-packaged-darwin-arm64-*.json系列。测量工具本身在 scripts/desktop-shell-metrics.sh,迁移整体规划与门禁在 docs/DESKTOP_SHELL_MIGRATION.md,Electron 壳架构与构建方式在 desktop/electron/README.md。
【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考