macOS
Swift
开发
性能

原生 Mac 开发:为什么 Electron 并不总是足够的

2025年11月3日
HarborDB 团队

在 HarborDB,我们早期做出了一个有争议的决定:我们使用 Swift 和 SwiftUI 构建了一个原生的 macOS 应用程序,而不是使用像 Electron(VS Code、Slack(很重)、Discord 等使用)或 Tauri 这样的跨平台框架。

在一个“一次编写,到处运行”是默认口号的时代,选择原生似乎是一种倒退。以下是我们对 2025 年真正的原生软件开发的技术和哲学辩护。

性能论点:内存和线程

Electron 的开销

每个 Electron 应用程序都捆绑了一个完整的 Chromium 实例和 Node.js。

  • 空闲 RAM 使用量:一个“Hello World”窗口约为 150MB。
  • 实际 RAM 使用量:Slack 经常使用 >1GB 仅仅为了显示文本。
  • 架构:每个窗口都是一个单独的渲染器进程。主进程(Node)和渲染器(UI)之间的通信需要序列化(IPC),这对于大量数据来说很慢。

原生优势

SwiftUI 应用程序共享已加载到内存中的操作系统库。

  • 空闲 RAM 使用量:~15-30MB。
  • 数据处理:我们可以将内存指针直接从数据库引擎 (C++) 传递到 UI 层 (Swift),而无需复制数据(零拷贝)。

具体示例: 将 100,000 行加载到表中。

  • Electron:必须序列化 JS 对象 -> IPC -> 在渲染器中反序列化 -> 生成 DOM。(明显的延迟)。
  • Swift:将结构加载到内存中 -> NSTableViewList 立即滚动,仅渲染可见内容。

深度系统集成

做一个“正经的 Mac 应用程序”不仅仅意味着顶部有菜单栏。这意味着支持 Mac 用户付费使用的功能。

1. 键盘快捷键和焦点

Web 应用程序经常处理不好复杂的键盘焦点。你有试过从 Web 应用程序中的代码编辑器中 Tab 出来吗? macOS 的原生响应者系统 (NSResponder) 以可预测和标准的方式处理事件传播。

2. 文件系统

HarborDB 是一个数据库工具。它需要读取 SQLite 文件、海量 SQL 转储和 CSV 导出。 出于安全原因,浏览器(以及通过扩展的 Electron)被积极地“沙盒化”。虽然 Electron 可以访问文件系统,但体验永远不如原生的 FileCoordinator 框架那样顺畅,该框架处理:

  • 文件锁定。
  • 原子更新。
  • 与 iCloud Drive 协调。

3. 服务和 Automator

原生应用程序公开“服务”。你可以在 Finder 中右键单击 .db 文件并查看自定义操作。你可以通过 AppleScript 或快捷指令编写脚本。

“原生软件尊重用户的计算机。它不假装它是唯一运行的程序。”

开发体验 (DX):Swift vs Typescript

这有点主观,但请听咱们说。

TypeScript太棒了。它是构建 Web UI 的最佳工具。但 JavaScript 生态系统很脆弱。node_modules 中有 10,000 个依赖项,复杂的 webpack/vite/rollup 配置,以及不断的变化。

Swift是强类型的、编译的,而且非常快。 使用 SwiftUI,构建声明性 UI 与 React 一样快,但具有:

  • 编译时真正的类型安全(没有 any)。
  • 直接绑定到 C++ API(通过 Objective-C++ 或 Swift C Interop)。
  • 令人难以置信的分析工具 (Xcode Instruments),可以准确向你显示哪一行代码正在分配内存或阻塞主线程。

为什么不是每个人都使用原生?

如果原生这么好,为什么 Electron 会赢?

  1. 跨平台:这是显而易见的原因。
  2. 招聘:有 100 个 React 开发人员对应 1 个 Swift/macOS 开发人员。
  3. 迭代速度:推送 Web 更新是即时的;推送原生应用程序更新需要 App Store 审核或 Sparkle 更新。

我们的赌注

我们打赌,工匠级软件质量是有市场的。 专业用户已经厌倦了感觉不像应用程序的慢速应用程序。他们厌倦了电池电量耗尽,因为他们的聊天应用程序正在挖掘加密货币(开玩笑,但也差不多)。

HarborDB 很快。它在 200 毫秒内打开。它以 120 FPS 的速度滚动 100 万行。它尊重你的键盘快捷键。

这可能是老派,但对我们来说,这是专业生产力的未来。