去年九月,我们推出了面向 iOS 和 Android 的 Proton Mail 重大更新。
从表面上看,新应用带来了现代化的设计、更出色的性能和离线功能,但远不止于此。在这背后,这些应用是在一套全新的技术栈上对 Proton Mail 进行的彻底重写,该项目内部代号为 Engineering Transformation。使用 novel 一词是有意为之,因为据我们所知,这是所选技术首次被用于成熟的生产应用之中。
本文旨在揭示我们团队在创造这场变革的过程中所经历的精彩旅程,并回答社区在此期间向我们提出的一些问题。首先,其背后的根本原因在于需要改变现状。
一切从何开始
2023 年十月的一个周五晚上,我们意识到必须做出改变。这一念头异常清晰地浮现,但并非凭空而来:几个月来,我们一直试图为影响用户 Mail 和 Calendar 移动产品体验的种种看似无关的问题寻找共性,这一领悟正是由此累积而成。
尽管可能过于简化,我们仍可将痛点归纳为以下三个方面:
质量: 单就 Mail iOS 和 Mail Android 各自而言,它们在质量和性能方面均未达到预期。
iOS 与 Android 之间的功能差距: 部分功能仅在其中一个平台上可用,另一个平台何时跟进尚无明确时间表。
工程效率: 关键更新和期待已久的功能未能在两个平台上及时交付。
其中一些问题超出了移动端的范畴,要解答它们就需要从技术领域延伸到组织扩张这一引人入胜的问题空间,尤其是快速增长的科技初创公司。但移动生态系统的脆弱性很大程度上根源于技术和架构。
移动工程的规模化
移动工程的规模化面临一系列独特的挑战,与后端和 Web 团队的规模化有着显著差异。这些差异源于平台碎片化以及移动生态系统的实际运营状况。移动团队通常需要支持跨多种操作系统和设备(手机、平板电脑,有时还包括可穿戴设备)的多个平台。iOS 和 Android 各有自成一体的编程语言、框架和工具链,这导致大量重复工作:多个团队、重复的代码库,以及平台特定工作与产品相关工作之间不断的权衡取舍。要让产品功能保持同步,需要巨大的协调成本。
这虽是全行业面临的挑战,但对 Proton 而言尤为严峻。Mail 和 Calendar 这类功能型应用本身就比市面上大多数移动应用更为复杂。再加上处理端到端加密所需的额外客户端逻辑层,最终造就了格外“厚重”的客户端。当时,Android 团队正忙于按更高的质量标准重写 Mail——这项投入耗费了将近 18 个月。iOS 也亟需重新架构,更不用说 Calendar 了。重复开发的成本不断侵蚀我们的工程资源,我们清楚地认识到,重复以往的做法无法带来成功。
意识到自己陷入停滞的最大好处在于,它会促使你跳出当前现状的束缚去思考。如果能够摆脱将我们带到今天这个局面的种种选择与承诺的负担、从头再来,我们会怎么做?仔细研究过去十年成功企业如何应对这一问题,你会发现它们遵循的只有两种可行策略:
- 用钱解决问题,组建越来越庞大的团队,靠源源不断的投资和/或丰厚的回报来抵消高昂的运营成本。但对于 Proton 不依赖风投的商业模式而言,这并不可行:我们无法在支出上与依靠广告、获得投资者支持的竞争对手抗衡。
- 对应用进行再工程以消除浪费,即(尽可能)使用共享代码库来构建应用。
方案 1 既然行不通,前方的道路便已确定。
达成目的的手段:选择合适的技术栈
下一步是选择一套真正能够胜任这项工作的技术栈。
过去 15 年里,跨平台移动开发领域涌现出大量“一刀切”的解决方案:HTML5、Xamarin、React Native、Flutter、Kotlin Multiplatform 等等。每一个都带着同样的承诺而来——彻底取代原生开发。但在实践中,大多数方案要么彻底失败,要么只能在受限极窄的问题空间内取得成功。世上并不存在一种能让平台差异消失的通用抽象:任何发布并维护过大型移动应用的人都深知这一点。唯一可靠的出路是从具体需求出发倒推,而不是顺着工具潮流前行。
我们将这一最终目标转化为一系列不可妥协的要求 (1),任何候选方案都必须满足这些要求,并在整个评估过程中将其作为指导框架:
- 成本与时间: 该技术栈必须能切实降低在 iOS 和 Android 上发布、维护和演进 Proton Mail 所需的成本和时间。
- 用户体验: 它必须保持接近原生的性能和交互质量——达不到这一点就免谈。
- 面向未来的战略考量: 该方案必须经得起长期使用。我们有意识地避免使用第三方框架,以免我们的路线图依赖于其他厂商的持续支持。
前两个约束之间的矛盾正是行业版的圣杯:“一种能提供原生应用性能和用户体验的跨平台解决方案。”
从一开始,我们就对 React Native 或 Flutter——当时两大主流跨平台框架——能否达到这一标准持怀疑态度。尽管如此,我们还是通过构建 Mail 消息列表视图的概念验证实现来验证了这一怀疑。
React Native 很快暴露出其局限性。在大型数据集中滚动时,其解释执行模型的代价显得格外突出。Flutter 表现稍好,但界面仍然明显缺乏原生感,尤其是在 iOS 上。更重要的是,Flutter 是一个由 Google 控制的专有框架,而 Google 有过 放弃自有技术的前科(新窗口),并且不久前裁掉了 Flutter 团队的很大一部分。对于一款需要长期安全性和可靠性保障的产品而言,这种程度的外部依赖是无法接受的。
Kotlin Multiplatform 是下一个候选方案。它是一个颇具吸引力的选择——对于拥有深厚 Android 专业知识的组织尤其如此——但最终仍不适合我们的用例。缺乏共享 UI 层、成熟度存疑,以及其执行模型带来的额外开销,使它的缺点盖过了优点。
至此,结论已十分清晰,并与我们最初的直觉一致:唯一能够稳定接近预期结果的架构,就是刻意设计的混合技术栈。每个平台上使用原生 UI——Android 上用 Jetpack Compose,iOS 上用 SwiftUI——并由一个用高性能底层语言编写的共享业务逻辑层作为支撑。这一做法有先例可循:Dropbox 曾著名地使用 C++ 在移动平台之间共享业务逻辑,后因该语言的运维和认知成本于 2019 年放弃。
到 2023 年底,Rust 已明显成为系统编程语言谱系中的接班人。
Rust 拥有与 C++ 相当的性能表现,却没有其许多历史遗留问题。它无需垃圾回收即可提供强大的内存安全保障,在编译期强制实现线程安全的并发,并得到一个庞大且实力雄厚的开源生态系统的支持。同样重要的是,Rust 能与原生移动语言——iOS 上的 Swift 和 SwiftUI、Android 上的 Kotlin 和 Jetpack Compose——无缝集成,使其成为在不损害 UI 层的前提下共享核心逻辑的务实之选。
这并非一个没有风险的决定。当时,以 Rust 为核心架构构建的大规模、面向消费者的移动应用寥寥无几,团队内的 Rust 经验也很有限。
但有意义的创新很少发生在低风险区域。真正的挑战不在于 Rust 本身,而在于组织惯性——在清晰的约束条件和工程判断的指引下,从经过验证的保守做法转向有意识的实验探索。
全新的 Proton Mail:成果与经验
让我们快进到今天,看看这场豪赌的结果如何。
下图展示了 Mail 移动端的架构。Rust 核心负责应用业务逻辑的全部。我们将 Rust 的使用范围从其常见领域(网络、存储、算法计算)一路拓展到复杂导航逻辑的处理。消息列表无限滚动所依赖的逻辑便是一个典型例子。这种做法虽然非常规,但事实证明它是实现最大化代码复用这一目标的关键。最终,如今代码库中近 80% 的代码在 iOS 和 Android 之间共享。

这是否转化成了更快、更高质量的上市速度?虽然现在下最终定论还为时过早,但早期迹象已非常令人鼓舞:
- 在发布后的两个月里,团队成功地在两个平台上保持了每周一次的功能更新节奏(共发布 12 个功能版本)。
- 我们消除了平台之间的功能差距,为 Android 带来了期待已久的功能,如推迟、日历 RSVP 和滑动切换到下一封消息。
- 即使在这一早期阶段,新代码库在两个平台上都已证明比之前几代更稳定:iOS 崩溃率为 0.05%(此前为 0.12%),而 Android 的崩溃率则回落到历史基线水平 (0.19%)。这有力地印证了 Rust 的运行时稳定性。
在这种方法下,支持工作的扩展也更加高效。找出并解决一个共享的根本原因,往往比追查散布在两个独立代码库中、由略有不同的逻辑缺陷引发的表面相似的问题更快。在修复一类影响应用离线能力底层逻辑的类别同步问题时,我们为此前的工作假设找到了实证确认:一个根本原因,一个解决方案——即上图中随版本 7.6.2 发布的 Rebasing 模块。
硬币的另一面?
- 问题和功能退化可能会产生更广泛的影响,波及两个平台上的用户。鱼与熊掌难以兼得——但通过重点投入端到端(E2E)测试,无疑可以缓解这一风险。
- 如同任何沿水平技术分界线对面向用户的解决方案进行切分的做法一样,这有可能造成知识孤岛,并使工程精力在端到端用户体验上有所分散。你需要对此有所意识,并有意识地降低这一风险。最有效的措施包括:
- 让子团队专注于交付功能,而非技术层。
- 培训移动工程师成为“全栈”人才,即能够在 Rust 代码库和原生平台上进行调试、支持和开发。
Engineering Transformation 的下一步
从一开始,我们就清楚地认识到,这一项目的意义远不止于 Proton Mail 本身。将这一技术栈成功应用于 Proton 的旗舰应用,始终只是更漫长旅程的第一步——这段旅程的最终目标,是将这一方法推广到我们移动生态系统的其余部分。
这一设想如今正在成为现实。在我撰写本文之际,我们的帐户和支付 SDK 以及下一代 Proton Calendar 移动应用,正在按照这一新的技术方向进行重写。
这标志着第二波工程转型的开始——这一演进通过一套旨在让组件复用更加容易的架构框架来扩展技术蓝图,不仅跨平台,而且跨产品。虽然这一转型不会一蹴而就,但它对于打造客户期望 Proton 成为的无缝集成、隐私至上的生态系统至关重要。
(1):Simon Lewis,“A strategy for application implementation on multiple platforms”,2023 年。






