跳转到内容
Skip 中文站
3.2k

跨平台框架对比

Skip 与其他跨平台框架相比表现如何?下表围绕生产级移动应用最重要的几项标准进行评估:原生 UI、性能、平台 API 访问能力以及长期可维护性。

分别开发
两次
SkipFlutterReact
Native
Compose
Multiplatform
使用单一语言和
单一代码库开发
❌✅✅✅✅
现代、内存安全的语言✅✅✅✅✅
原生编译✅✅✅❌✅
内存高效
(不额外引入垃圾回收)
✅
✅
✅
✅
❌
❌
❌
❌
❌
✅
iOS
Android
平台原生控件✅
✅
✅
✅
❌
❌
✅
✅
❌
✅
iOS:原生 UIKit
Android:原生 Views
平台厂商推荐的工具包✅
✅
✅
✅
❌
❌
❌
❌
❌
✅
Apple:SwiftUI
Google:Jetpack Compose
轻松访问平台 API✅
✅
✅
✅
❌
❌
❌
❌
❌
✅
iOS:Swift
Android:Kotlin
可脱离框架继续开发不适用✅❌❌❌

下表进一步拆解各框架底层采用的技术栈。

SkipFlutterReact NativeXamarinKMP ComposeIonic/Cordova
开发语言SwiftDartJavaScriptC#KotlinJavaScript
UI 框架SwiftUIFlutterHTML/JSX+CSSXAML/MAUIComposeHTML+CSS
包管理器SwiftPMPub/CocoaPodsNPMNuGet/CocoaPodsGradle/CocoaPods各不相同
IDEXcodeAndroid StudioVSCodeVisual StudioIntelliJ IDEAVSCode
iOS 用户体验原生模拟原生原生原生模拟原生HTML
Android 用户体验原生模拟原生原生原生原生HTML
渲染方式原生Impeller/SkiaFlexbox原生SkiaWebView
代码执行方式编译执行编译执行解释执行编译执行编译执行解释执行
平台 API 调用直接桥接桥接桥接混合桥接
额外 VM/运行时无Flutter EngineHermesMonoKotlin/Native各不相同
额外垃圾回收器无是是是是是

以上表格给出了整体概览。下面将结合独立基准测试、生产事故复盘和分析机构评估,深入考察各个主要替代方案,并说明它们在哪些方面难以满足生产级移动团队的实际需要。

Flutter 是 Google 推出的跨平台 UI 工具包,以 Dart 编程语言和自定义渲染引擎为核心。按开发者数量计算,它是应用最广泛的跨平台框架,并且确有优势:高效的热重载流程、庞大的控件库,以及可编译到多个平台的单一代码库。不过,Flutter 的架构选择也带来了一系列取舍;随着应用逐渐成熟、平台体验持续演进,这些代价会越来越高。

Flutter 最具代表性的架构选择,是完全绕过平台原生 UI 工具包。它不使用 iOS 的 UIKit 或 SwiftUI,也不使用 Android Views 或 Jetpack Compose,而是通过自己的渲染引擎(Skia 或其后继者 Impeller)绘制每个像素。最终界面只能模拟各平台的外观,并未真正采用平台自身的组件。

这造成了业界所谓的“恐怖谷” ↗问题:Flutter 应用看起来接近原生,却总有些不对。滚动物理效果、文本选择行为、上下文菜单,以及无障碍语义等系统级集成,都与各平台用户的预期存在细微差异。这些差异会不断叠加。用户可能说不清 Flutter 应用为什么显得“别扭”,但整体体验质量通常低于使用平台原生工具包构建的应用。

iOS 26 与 Apple“Liquid Glass”设计语言发布后,这种架构的后果变得格外明显。SwiftUI 应用会自动采用新的视觉样式;Flutter 团队却确认 ↗,目前不会在 Cupertino 库中开发新的 Apple 26 版 UI 特性,也暂不接受相关贡献。在 Flutter 团队从头重新实现 Apple 的设计变化之前,iOS 26 上的 Flutter 应用会显得过时,而这一工作尚无公开时间表。正如一篇分析 ↗所指出的,在 Flutter 中为 iOS 和 Android 分别按条件渲染符合平台习惯的 UI,其成本已接近直接编写两套原生应用。

相比之下,Skip 应用在 iOS 上使用 SwiftUI,在 Android 上使用 Jetpack Compose,无需重新实现平台界面。当 Apple 或 Google 更新设计语言时,Skip 应用会像其他原生应用一样直接继承这些变化。

Dart 运行时与垃圾回收带来的性能开销

Section titled “Dart 运行时与垃圾回收带来的性能开销”

Flutter 会在每个应用中打包 Dart 虚拟机及其垃圾回收器。Flutter 自身问题跟踪器中的独立测量 ↗显示,一个最小 Flutter 应用启动时约占用 40 MB 内存,而等效的 Android 原生应用约为 20 MB。其图形内存占用达到原生基线的 2.3 倍,原生库开销则高出 6 倍。AltexSoft 的分析 ↗发现,Flutter 的内存用量甚至比 React Native 还高约 50%。

Dart 垃圾回收器对流畅界面尤其不利。一个长期存在的 Dart SDK 问题 ↗记录了滚动期间频繁且持续时间较长的垃圾回收暂停,有时仅在基础控件上每次滑动都会触发。问题具有结构性:Flutter 大量使用控件对象,会创建许多生命周期很短的对象,GC 必须不断回收它们。在 90 Hz 或 120 Hz 屏幕上,每帧预算分别只有 11 ms 或 8 ms,即使短暂的 GC 暂停也会造成肉眼可见的卡顿。

Skip 不会向 iOS 应用添加运行时或垃圾回收器。在 Android 上,Skip Fuse 原生编译 Swift,Skip Lite 则生成在平台自身运行时上执行的标准 Kotlin。两种模式都不会增加与 UI 线程争抢执行时间的额外 GC 层。

最小 Flutter 应用的体积约为 15~20 MB,而 Android 原生应用通常为 2~4 MB,iOS 原生应用为 1~3 MB。额外体积来自渲染引擎、Dart 运行时和国际化组件库 ICU。加入任何应用专用资源之前,功能较完整的 Flutter 应用通常已经达到 25~35 MB ↗。相比之下,使用 SkipZero 的 Skip iOS 应用最小可至 25 KB ↗,因为 iOS 构建完全不依赖 Skip 框架。

2024 年 4 月,Google 在 Google I/O 前数周裁撤了 Flutter 和 Dart 团队员工 ↗。包括 Impeller GPU 后端主要实现者在内的关键工程师相继离职。Google 有大量终止产品和框架的历史记录 ↗,而 Flutter 又不直接为公司创造收入,因此在削减成本时更容易受到影响。Google 后续活动中重申了对 Flutter 的承诺,但裁员仍给已经重度投入该框架的组织带来不确定性 ↗,其中包括 Canonical 的 Ubuntu 桌面团队。

ThoughtWorks Technology Radar 于 2019 年 11 月将 Flutter 放入“试用(Trial)”象限 ↗,之后从未将其提升至“采用(Adopt)”,当前技术雷达中已不再出现 Flutter。

Skip 是开源、由社区资助且可完全脱离的方案。即使停止使用 Skip,你的 iOS 应用仍是纯净的 SwiftUI 项目,无需修改即可继续运行。


React Native 由 Meta 维护,使用 JavaScript(或 TypeScript)以及桥接架构来渲染平台原生组件。它拥有庞大的生态和广泛的社区采用度,也能把 Web 开发技能复用于移动端。但在实践中,这一框架会引入显著的复杂度、性能限制和长期维护成本,并随着应用增长而越来越难以控制。

React Native 的架构要求应用逻辑与原生 UI 之间的所有通信都经过桥接层。在旧架构中,跨越桥接层的每份数据都必须先序列化为 JSON,再由另一端反序列化。这项开销并非偶发现象,而是框架吞吐能力的核心限制。复杂列表、动画和数据密集型页面很容易让桥接层饱和,进而造成掉帧与交互迟缓。

Meta 一直在推进“新架构”(Fabric 渲染器、TurboModules 和 JSI 接口)以缓解这些限制,但即使资源充足的团队,迁移过程也十分痛苦。Shopify 工程团队记录 ↗了迁移 40 多个原生模块的经历:复杂组件的加载时间最多倒退 20%,无崩溃会话率最初也跌破 99.95% 的目标。旧架构已于 2025 年 6 月冻结 ↗,未完成迁移的团队如今处在不再受支持的路径上。

Skip 没有这种桥接层。在 iOS 上,SwiftUI 代码无需中间层即可运行;在 Android 上,Skip Lite 生成直接在平台执行的标准 Kotlin 和 Compose 代码,Skip Fuse 则原生编译 Swift。无需序列化层,不存在桥接开销,也不必规划架构迁移。

React Native 会在每个应用中嵌入 JavaScript 引擎 Hermes 及其垃圾回收器。2025 年跨框架基准测试 ↗测量了真实列表滚动场景中的内存用量:React Native 额外使用 45 MB,而原生 Swift 为 10 MB,相差 4.5 倍。其标准差也明显更高(10.94 MB 对 0.18 MB),说明负载下的内存行为更难预测。

Walmart Labs 的测试 ↗显示,Hermes 虽然启动效率较高,但 FlatList 加载约 920 个条目、内存达到 556 MB 后发生崩溃。持续负载下的垃圾回收行为难以预测,以至于 Shopify 明确表示 ↗,应用追求“100% React Native”应当被视为反目标。

React Native 要求开发者使用 JavaScript 或 TypeScript。对于已经掌握 Swift 的 iOS 团队和已经掌握 Kotlin 的 Android 团队,这意味着还要引入一套完全不同的语言生态、构建工具链(NPM、Metro bundler)及开发范式。实际项目通常仍需要原生语言能力来处理桥接、自定义模块和平台专用功能,因此所谓“一种语言”经常变成“三种语言”。

一家开发机构记录 ↗了自己的经历:一个 React Native 项目累计使用 42 个 NPM 依赖,其中 25 个在两年内被遗弃;可比的 iOS 原生应用只有 10 个依赖,其中仅 1 个过时。JavaScript 生态中库的快速更替带来了原生开发通常不存在的持续维护成本。

使用 Skip 时,开发语言是 Swift,UI 框架是 SwiftUI,与 iOS 原生开发采用的工具完全相同。不需要学习新语言,不需要维护 NPM 依赖树,也无需持续关注桥接模块是否被弃用。

最常被引用的案例是 Airbnb 在 2018 年决定 ↗放弃 React Native、回归完全原生开发。该公司发现,即使拥有约 100 名移动开发者,桥接开销、原生模块维护以及跨平台不一致仍难以持续承受。

或许更能说明问题的是 Meta 自己的选择。2023 年,Meta 构建 X/Twitter 的竞争产品 Threads 时,iOS 端采用原生 Swift/UIKit,Android 端采用 Jetpack Compose,并未在这款堪称其多年最受瞩目的消费者应用中使用自家的 React Native 框架。

ThoughtWorks Technology Radar 在 2016 年 11 月将 React Native 列入“试用(Trial)”象限 ↗,此后它再未出现在该技术雷达中。


Skip 与 Compose Multiplatform(KMP)对比

Section titled “Skip 与 Compose Multiplatform(KMP)对比”

Compose Multiplatform 由 JetBrains 开发,它将 Kotlin 的 Jetpack Compose 扩展到 iOS 等平台。其底层 Kotlin Multiplatform(KMP)技术用于共享业务逻辑,确有价值,Google 也在 Google I/O 2024 上认可了 KMP 的共享逻辑用途。但用于共享 UI 的 Compose Multiplatform 与 Skip 采用了根本不同的路径,对 iOS 优先团队尤其不利。

Compose Multiplatform 不使用 iOS 原生 UI

Section titled “Compose Multiplatform 不使用 iOS 原生 UI”

与 Flutter 类似,iOS 上的 Compose Multiplatform 完全绕过 UIKit 和 SwiftUI,通过基于 Metal 后端的 Skia ↗在自定义画布上绘制全部 UI。结果是在 iOS 上呈现 Material Design 风格,而不是原生 iOS 应用体验。由于没有 Cupertino 控件库 ↗,开发者只能在两个平台都接受 Material Design,或自行从头实现 iOS 风格组件。

独立的体积测量结果非常直观。Jacob Ras 的基准测试 ↗显示,一个简单 Compose Multiplatform iOS 应用大小为 24.8 MB,而等效的 SwiftUI 原生应用仅 1.7 MB,相差 14.6 倍。额外体积主要来自 Skia 渲染库:Android 已内置该库,但 iOS 应用必须额外携带二进制文件。JetBrains GitHub 问题 ↗中,有开发者报告在现有项目中集成 Compose 会增加 16 MB,并有人称其为“完全无法接受的问题”,因为它超过了 iOS App Clip 的大小限制。

Skip 在 iOS 上生成原生 SwiftUI,在 Android 上生成原生 Jetpack Compose。没有额外画布层,不打包渲染引擎,也没有相应的体积负担。SkipZero iOS 应用可以小于 25 KB。

Compose Multiplatform for iOS 在 2023 年期间仍处于 Alpha,2024 年 5 月进入 Beta ↗,直到 2025 年 5 月才随 1.8.0 版本被宣布为稳定 ↗。目前仍有一些功能处于实验阶段,生产团队报告 ↗对话框、流式行布局等常见组件曾不可用或需要自行实现。Guarana Technologies 指出 ↗,即使使用 KMP 共享逻辑,多数团队仍更倾向于使用原生 UI 来保证稳定性。

KTH 的一项学术基准研究 ↗发现,Compose Multiplatform 在 iOS 上执行复杂动画时会出现帧延迟,而原生实现能够保持无延迟的稳定性能。研究结论认为,该框架适合“简单动画和中等性能需求”,但在复杂场景中无法达到原生 Swift 的能力。

Skip 自 1.0 版本起已投入生产使用,并建立在 SwiftUI 与 Jetpack Compose 之上;这两套框架都已经过多年稳定的生产实践。

Compose Multiplatform 要求所有共享代码都用 Kotlin 编写。对于专长在 Swift 的 iOS 团队,这意味着还要学习并持续维护第二种语言能力。Kotlin 与 Swift 的互操作又进一步增加了问题:Kotlin/Native 目前通过 Objective-C 桥接导出到 Swift ↗,这会丢失泛型、折叠包命名空间、要求可空基本类型使用包装类型(例如 KotlinInt 而不是 Int?),并迫使 Swift 调用方传入每个参数,即使 Kotlin 已定义默认值。JetBrains 正在开发直接 Swift Export ↗,但截至 Kotlin 2.2 仍处于实验阶段,不支持函数类型,也无法处理跨语言继承。

Skip 采取相反路线:开发语言是 Swift,共享代码是 Swift,iOS 应用则是纯 SwiftUI。iOS 端不存在语言障碍和互操作桥接,Android 端与 Kotlin、Java 的互操作也简洁直接。

Kotlin/Native 使用“停止世界”标记与并发清扫式垃圾回收器,并与 Swift ARC 同时运行。独立测量 ↗显示,压力条件下 GC 周期可能达到 10 ms;XCFramework 构建产生的 GC 次数也远高于共享库构建(157 次对 31 次)。JetBrains 自己的 Compose 1.7.0 发布说明 ↗承认,LazyGrid 基准中的 GC 暂停从 1.7 ms 降至 0.4 ms,间接证实此前的暂停已足以在标准刷新率下造成掉帧。

Skip 不会向 iOS 应用添加垃圾回收器。iOS 代码以原生 Swift 和 ARC 运行,不存在第二套内存管理系统争夺每帧执行预算。

Compose Multiplatform 主要是 JetBrains 产品,并非 Google 产品。Google 在 I/O 2024 对 KMP 的认可针对共享业务逻辑,而不是共享 UI 渲染方案 ↗。JetBrains 维护完整跨平台工具链的能力也受到质疑:2025 年 2 月,该公司取消了 Fleet 中的 KMP 支持 ↗;与此同时,Apple 的平台限制使完整 iOS 开发工具无法在 Windows 和 Linux 上运行,形成了 JetBrains 无法单方面解决的结构性依赖。

ThoughtWorks Technology Radar ↗将 Kotlin Multiplatform Mobile 放在“试用”环,意为“值得尝试”,但仍有风险,尚未达到“采用”建议级别。大型项目中的扩展性挑战 ↗也已有记录,包括每个 iOS 应用只能支持一个 KMP 框架,以及无法在独立编译的框架之间传递自定义类型。

Skip 是开源并由社区资助的项目。iOS 端依赖 Swift 与 SwiftUI,Android 端依赖 Kotlin 与 Jetpack Compose;它们分别由 Apple 和 Google 维护,也是各平台厂商推荐的工具。Skip 的作用是在两者之间建立联系,而不是替代任何一方。