🔄 Raycast 2.0 重写深度解析:从原生到混合架构的全面迁移

> 来源: https://www.raycast.com/blog/a-technical-deep-dive-into-the-new-raycast

> 日期: 2026-05-14

> 作者: Raycast Engineering Team

一句话版本

Raycast 2.0 是一次从纯原生 macOS AppKit 到混合架构(Swift/C# 原生壳 + React WebView UI + Node 后端 + Rust 核心)的完整重写,让一个代码库同时运行在 macOS 和 Windows,同时保持原生手感。

核心内容

背景

Raycast 在 2023 年底开始规划 Windows 版本,当时 v1 已经是原生 macOS Swift/AppKit 应用但面临瓶颈:

代号 X-Ray(Cross-platform Raycast)。

技术选型:为什么选混合架构

团队评估了六种方案,最终选择最困难的道路:

方案结果原因
**纯原生双平台**Windows 原生框架生态差;两套 UI 栈 = 两倍工作
**Electron**需要深层 OS 集成(热键、剪贴板、辅助功能、浮动面板);不想捆绑 Chromium
**Tauri**当时太年轻,控制力不够
**Flutter/Qt/React Native Desktop**控制力或生态不足
**混合架构(自有)**原生壳 + 系统 WebView + Node + Rust,完全控制所有层

一个 quote 很精辟:

> "我们不是 Web App 洒了点原生调料。我们是原生 App 用 Web 做 UI。"

四层架构


┌──────────────────────────────────────┐
│      Host App(原生壳)               │
│  macOS: Swift + AppKit               │
│  Windows: C# + .NET 8 + WPF          │
│  窗口/热键/菜单栏/系统托盘            │
├──────────────────────────────────────┤
│    Web Frontend(UI — 一套代码)      │
│  React + TypeScript                  │
│  系统 WebView 渲染                    │
│  (WKWebView / WebView2)              │
├──────────────────────────────────────┤
│     Node Backend(业务逻辑)          │
│  数据库 / 扩展运行时 / 长驻服务       │
│  双平台共享,功能开发一次完成          │
├──────────────────────────────────────┤
│      Rust Core(性能关键)            │
│  文件索引器 / 数据层 / 同步引擎       │
│  与 iOS App / 服务端共享              │
└──────────────────────────────────────┘

层间通信:平台消息处理器 + stdio transport。接口声明统一,自动生成类型化客户端——跨四个运行时的编译时保证。

最精彩的部分:让 WebView 感觉像原生

团队花了大量篇幅讲述如何驯服 WebKit——它被设计用于浏览器,不是每天显示/隐藏数百次的启动器。

六大 WebKit 坑及解法:

1. 节流:WebKit 在 view 不可见时暂停动画/timer → 窗口 alphaValue=0 保持视觉隐藏,禁用 occlusion detection

2. 展开闪烁:从紧凑到全屏时 WebKit 留白 → WKWebView frame 永远保持展开尺寸,内容提前渲染

3. 缩放卡顿:WebKit 在动画缩放时暂停绘制 → 重写 NSWindow.setFrame,用隐式 Core Animation

4. 窗口打开闪烁:WebView 绘制完才显示 → 用 _doAfterNextPresentationUpdate 同步渲染状态

5. Emoji 渲染慢:每个 emoji 回退字体链 → 启动时预加载 emoji 字体

6. 运行时 Feature Flags:构建基础设施解锁 60FPS、启用 requestIdleCallback

Windows 端:WebView2 的 Chromium 也有自己的节流逻辑。每个窗口需要独立 WebView2 环境(丙烯酸效果、自定义 chrome、输入处理)。

自建 Rust 文件索引器

v1 依赖 Spotlight 元数据,Windows 不能用。

v2 用 Rust 重写文件索引器:独立进程、直接扫描文件系统、文件事件保持更新。

Windows 上直接读取 NTFS Master File Table —— 数秒扫描整个硬盘的唯一可行方案。

内存:坦诚的数字

v1v2
典型使用200–300 MB**350–450 MB**

v2 隐藏时分布

团队强调:Activity Monitor 的数字不是表面那么简单——压缩内存、脏页/干净页、共享框架都有影响。真正指标是 Memory Pressure 颜色。

Trade-offs 总结

变好的

变难的

其他值得注意的技术细节

项目关联

评分

维度评分说明
技术深度⭐⭐⭐⭐⭐WebKit 适配细节极其珍贵,极少有团队公开分享
透明度⭐⭐⭐⭐⭐诚实承认内存增加、列出所有 trade-offs
架构决策⭐⭐⭐⭐⭐"不做 Electron"的 reasoning 说服力极强
阅读价值⭐⭐⭐⭐⭐2026 年最值得读的桌面工程文章之一

综合评分:5.0 / 5.0 — 如果你做桌面应用或者考虑跨平台,这篇文章是必读的。WebKit 适配那部分每一段都值回票价。

链接