Flutter 和 Compose 现在的真实竞争格局
Flutter 和 Compose 现在的真实竞争格局
Compose 1.0 正式发布的时候,Google 搞了个挺隆重的线上发布会,我在 YouTube 上看直播,弹幕里有人刷 "Flutter killer 来了"。那是 2021 年 7 月,Flutter 2.2 刚发布不久,跨平台势头正猛。三年多过去,2024 年的现在,再看这个判断,只能说当时的乐观和现在的现实之间,差了一个太平洋。
两个项目的出身决定了它们不是一路人
很多人把 Flutter 和 Compose 放一起比较,默认它们是同类产品,这个起点就错了。Flutter 从第一天就是跨平台框架,2017 年 Google I/O 亮相,目标明确:一套代码,iOS、Android、Web、桌面全跑。它的渲染层自己画,Skia 引擎直接怼到 GPU 上,不跟原生 UI 组件打交道。这种架构选择很激进,也意味着 Flutter 团队要维护一整个图形栈,从文本渲染到输入法,从无障碍到屏幕旋转,全自己扛。
Compose 完全是另一条路。它 2019 年作为 Jetpack 库预览发布,2021 年 1.0 稳定版,定位是 Android 原生的现代 UI 工具包,替代 View 体系。Compose 的渲染最终还是走到 Android 的 Canvas 上,依赖 Android 的渲染管线,依赖 Android 的生命周期,依赖 Android 的一切基础设施。Google 后来推 Compose Multiplatform,那是 JetBrains 在主导,跟 Google 的 Android Compose 团队基本是两拨人。
所以你看,Flutter 是 "我要造一个新世界",Compose 是 "我要把 Android 的旧世界翻新"。出身不同,基因不同,后来走向不同,再正常不过。
Google 的资源分配暴露了真实态度
有个细节很多人没注意:Flutter 和 Compose 在 Google 内部从来不是同一个老板。Flutter 归属 Google Cloud 相关的组织(中间经历过几次调整,现在在 Developer X 下面),Compose 是 Android 团队亲儿子。Android 团队每年 I/O 的 keynote 时间有限,Compose 占多少、Flutter 占多少,本身就是信号。
2023 年 Google I/O 是个转折点。那年的 Android 主题演讲里,Compose 的篇幅明显压缩,反而花了大量时间讲 AI、讲大模型、讲 Magic Compose 这种 Gmail 里的生成式文本功能。Flutter 的 session 被塞到了第二天,位置边缘。到了 2024 年,情况更微妙——Flutter 3.22 发布是在 I/O 前一周单独发博客,I/O 现场几乎没提。同期 Compose 也没拿到什么重磅更新,3.0 版本遥遥无期。
Google 的裁员动作更能说明问题。2023 年初那波裁员,Flutter 团队被砍了相当比例的人,据传接近 10%。有个在 Google 的工程师后来在 Blind 上吐槽,说 Flutter 的 PM 被并到了更大的 "跨平台解决方案" 组里,不再独立汇报。反观 Android 团队,虽然也有裁员,但 Compose 的核心开发组基本没动,甚至还在招人做 Compose for Wear OS 和 Compose for TV。
这不是说 Google 要放弃 Flutter,但优先级排序很清楚了:Compose 是 Android 生态的基建,必须保;Flutter 是战略探索,能跑就跑,跑不动就收缩。Google 从来不是慈善家,两个项目争资源的时候,亲儿子赢。
跨平台这块,Flutter 的麻烦不是 Compose 而是自己
Flutter 真正的困境,不是 Compose 抢了多少市场,而是它自己承诺的跨平台蓝图兑现不了。
桌面端是最明显的坑。Flutter 的 Windows、macOS、Linux 支持从 2022 年 3.0 开始号称 "stable",实际用起来完全是另一回事。我去年接了个小项目,要给内部工具做桌面版,试了 Flutter Windows。窗口管理一团糟,系统托盘要自己写插件,原生菜单栏集成度几乎为零。最离谱的是输入法,中文输入在 Windows 上候选框位置随机漂移,Issue #107809 开了两年没人修,最后是个社区成员提的 PR 临时解决。
Web 端更尴尬。Flutter Web 有两种渲染模式:HTML 和 CanvasKit。HTML 模式性能差,包体小;CanvasKit 用 WebAssembly 加载 Skia,性能好但首屏加载要下几 MB 的 wasm。实际项目里选哪个都是妥协,SEO 基本不用想,搜索引擎爬不了 Canvas 里的内容。很多团队试了一圈,最后 SSR 方案还是用 Next.js 或者 Nuxt,Flutter Web 只敢用在后台管理系统这种封闭场景。
所以 Flutter 的跨平台故事,讲到最后还是集中在移动端。但移动端里,iOS 的份额和体验一直是 Flutter 的软肋。苹果自己的 SwiftUI 在 iOS 15 之后进步很快,虽然 bug 也不少,但毕竟是第一方框架,跟系统特性同步。Flutter 的 iOS 实现要追新特性总是慢半拍,iOS 17 的 StandBy 模式、Interactive Widgets,Flutter 社区等了小半年才有不完整的支持。
Compose Multiplatform 这边,JetBrains 倒是务实。他们不碰 iOS 原生渲染,而是走 Kotlin/Native 编译到 iOS 可执行文件,UI 层用 Compose 的通用 API,底层实际调用 UIKit。这个方案在 2023 年底进入 beta,实际体验是:能跑,但跟 Flutter 的 iOS 支持半斤八两,都是 "能用,别细究"。JetBrains 自己也知道局限,官方文档里明确写了 "not recommended for production apps with complex UI",这话 Flutter 团队打死不会说。
国内市场的分化特别明显
看国内大厂的选择,比看 Google 的发布会更能说明问题。
字节跳动是 Flutter 的重度用户,抖音、今日头条的 Android 版都有大量 Flutter 模块。但字节内部有个 "Flutter 优化中台",专门做性能调优和崩溃治理,说明原生框架扛不住的业务才上 Flutter,上了之后还要大量投入维护。2023 年有传闻说字节在部分新业务线尝试 Compose,没大规模推广,但技术选型会里 Compose 的权重明显上升。
阿里系的淘宝、支付宝,Flutter 用得早,但踩坑踩得狠。支付宝 2022 年做过一次技术债清理,把部分 Flutter 模块回退到原生,原因是包体积和启动速度压不下来。淘宝的详情页曾经全 Flutter,后来改成混合方案,核心链路用原生,边缘模块用 Flutter。这种 "混用" 模式其实最累,两套框架并存,调试成本翻倍。
美团、拼多多这些后来者反而更激进。美团外卖的商家端、拼多多的部分活动页,直接上 Compose。他们的逻辑很实在:业务主要在 Android,iOS 份额相对低,Compose 的开发效率够用了,不需要为了一套代码跨平台牺牲 Android 端的体验。这跟 Flutter 早期 "write once, run anywhere" 的洗脑包形成鲜明对比——很多团队现在想通了,"run anywhere" 的代价是 "run well nowhere"。
有个反例是闲鱼。闲鱼是 Flutter 在国内的标杆案例,从 2019 年全量 Flutter 到现在,技术博客发了几十篇。但仔细看他们的分享,大量篇幅在讲怎么解决 Flutter 的内存泄漏、怎么治理混合栈的崩溃、怎么定制引擎减包体积。这些不是 "Flutter 真好用" 的证据,是 "Flutter 真难用但我们投入了几十人团队硬扛" 的证词。普通团队没这个资源,学不来。
开发体验的细节差距被低估了
比宏大叙事更重要的是日常开发里的小事。
Flutter 的热重载(Hot Reload)一直是卖点,但实际用起来有诸多限制。修改了 main 函数、修改了全局变量、修改了类的继承关系,热重载会失败,得冷启动。Dart 的编译器在复杂项目里越来越慢,我手头一个 30 万行 Dart 代码的项目,Debug 模式冷启动要 12 秒,这还叫 "快" 吗?
Compose 的热重载依托于 Android Studio 的 Apply Changes,机制不同,限制也不同。Compose 的 @Preview 注解是个被低估的神器,可以在 IDE 里直接渲染单个 Composable,不依赖运行设备,改完代码秒级刷新。这个体验做 UI 调优的时候比 Flutter 的模拟器方案顺畅得多,尤其是处理列表、动画这种需要反复微调的场景。
依赖管理也是 Compose 的优势区间。Flutter 的 pub.dev 生态增长很快,但包质量参差不齐。很多插件是个人维护,作者弃坑后没人接盘。我 2022 年用的一个蓝牙插件,作者停更后 fork 了三个社区版本,各修各的 bug,互不兼容。Android 的 Gradle 生态虽然也被吐槽,但 Maven Central 的存量库巨大,很多功能不需要额外插件,Android 原生 API 直接能用。
Compose 的互操作性是另一个杀手锏。现有项目里 90% 的 View 代码,可以渐进式迁移到 Compose,不需要重写。AndroidView 这个 API 允许在 Compose 里嵌入任意 View,ComposeView 允许在 View 里嵌入 Compose。这种 "混着用" 的能力,对大厂存量项目太重要了。Flutter 的混合方案是 PlatformView 和 FlutterView,但嵌入原生 View 的性能开销大,而且手势冲突、焦点管理全是坑,闲鱼的技术博客里有大量篇幅讲这个。
性能比较的真相
网上很多 Flutter vs Compose 的性能对比,多数不靠谱。实验室环境跑个列表滚动帧率,得出 "A 比 B 快 20%" 的结论,对实际项目没什么指导意义。
Flutter 的渲染管线是独立的,Skia 直接画到 Surface,理论上少了 Android 的 View 层级遍历,应该更快。但代价是:Flutter 的每一帧都要自己合成、自己处理平台消息、自己管理纹理。在低端 Android 机上,Flutter 的内存占用通常比原生高 20-30%,因为 Skia 的渲染缓存、Dart 的 GC 堆、Flutter 引擎自身的线程池,都是额外开销。
Compose 走 Android 的渲染管线,意味着它继承了 Android 渲染的所有问题,但也享受所有优化。Android 14 的 predictive back gesture、新版本的渲染线程优化、GPU 驱动的改进,Compose 自动受益。Flutter 要适配这些,得等引擎升级,通常滞后一个版本周期。
我实际测试过一个场景:复杂列表快速滑动,item 包含网络图片和文字。Flutter 用 ListView.builder + CachedNetworkImage,Compose 用 LazyColumn + Coil。在 Pixel 6 上两者帧率都接近 60fps,差距不明显;在 Redmi 9A 这种 4GB 内存的低端机上,Flutter 的掉帧次数明显更多,且伴随 GC 卡顿。Compose 也不是完美,但系统级的内存管理和渲染优化帮它兜底了。
启动速度是 Flutter 的硬伤。Flutter 的 APK 里要打包 libflutter.so,Dart 的 AOT 编译产物,还有资源文件。空项目的 Flutter APK 体积在 15MB 左右,Compose 的空项目可以压到 3MB 以下。这个差距在新兴市场、低端设备、流量敏感场景下,直接影响业务决策。
生态位正在重新划分
2024 年的现状,我觉得可以这么概括:
Flutter 退守到了 "跨平台刚需" 的 niche 里。你的团队同时做 iOS 和 Android,人员配比做不到 1:1,或者业务需要快速覆盖两个平台,Flutter 还是合理选择。但前提是你能接受它的性能天花板、能接受 Google 的资源投入不确定性、能自己搞定桌面和 Web 的残缺支持。字节、阿里、腾讯的部分业务还在用 Flutter,不是因为它完美,是因为迁移成本太高,骑虎难下。
Compose 在 Android 端基本站稳了。新开的 Android 项目,技术选型会里 Compose 的通过率越来越高。Google 自己的应用也在迁移,Google Play、Google Drive 的 Android 版都有 Compose 模块。JetBrains 推 Compose Multiplatform,野心是跨平台,但现阶段更像 "Kotlin 生态的粘合剂",让 Android 开发者能复用业务逻辑到 iOS,UI 层该写 SwiftUI 还是写 SwiftUI。
有个中间地带在崛起:React Native 的新架构(Fabric + TurboModules)和 Expo 的完善,让 JS 跨平台的体验大幅提升。TikTok 的某些模块、Shopify 的新应用,在尝试 React Native。这不是 Flutter 或 Compose 的直接对手,但分流了 "跨平台" 这个大盘子里的注意力。Google 内部对 Flutter 的投入收缩,跟 React Native 生态的成熟也有关系——跨平台方案不止一家了,Google 没必要 all in。
对开发者的实际建议
如果你现在面临技术选型,我的看法很直接:
纯 Android 团队,没 iOS 业务,上 Compose。不要犹豫,不要想着 "万一以后要做 iOS 呢"。Compose 的开发效率、工具链成熟度、与现有代码的互操作性,都是当下最优解。Compose Multiplatform 可以观望,但别把它作为决策依据,JetBrains 的路线图经常跳票。
已经有 Flutter 项目的,评估迁移成本。如果 Flutter 模块边界清晰、业务逻辑和 UI 分离得好,可以考虑把 Android 端逐步切到 Compose,iOS 端保持 Flutter 或转 SwiftUI。全量重写很少划算,渐进式迁移更现实。
从零开始要做 iOS + Android 的,Flutter 还是 React Native 二选一。Compose Multiplatform 目前不适合作为主力方案,除非你的团队全是 Kotlin 背景、iOS 端能容忍较高的原生开发比例。这个建议可能跟 JetBrains 的营销话术冲突,但我看过太多 "先用 Compose Multiplatform 试试" 的项目,半年后默默加招 iOS 原生开发。
Web 端需求强的,两个都别选。Flutter Web 和 Compose for Web(基于 Kotlin/JS 的实验性项目)都是坑。Next.js、Nuxt、或者更激进的 htmx,才是当前的主流解法。
一个没被充分讨论的问题
Compose 和 Flutter 的竞争,背后其实是 Google 和 JetBrains 的微妙关系。
JetBrains 是 Kotlin 的创造者,Compose 的核心编译器插件是 JetBrains 写的。Google 把 Kotlin 定为 Android 首选语言,但语言生态的控制权在 JetBrains 手里。Compose Multiplatform 是 JetBrains 主导,不是 Google,这意味着 Android 的 UI 未来可能分裂成两条线:Google 控制的 Android Compose,和 JetBrains 控制的跨平台 Compose。
Google 对此的态度很暧昧。一方面需要 JetBrains 的编译器技术,另一方面不想让 Android 生态的 UI 层被外部公司主导。Flutter 曾经是 Google 完全控制的跨平台方案,但投入收缩后,这个 "完全控制" 的价值也下降了。
对开发者来说,这种大厂博弈的具体影响很难预判。但一个观察是:JetBrains 在 IntelliJ IDEA 和 Android Studio 上的投入,直接影响 Compose 的工具链体验。而 Flutter 的 DevTools、IDE 插件,维护力度明显不如早期。工具链的衰减,是比框架本身更慢但更深的侵蚀。
结尾
写到这里,想起 2021 年那个 "Flutter killer" 的弹幕。三年后的今天,Compose 没杀死 Flutter,Flutter 也没杀死 Compose,但它们各自都老了不少。Flutter 的跨平台梦碎了一半,Compose 的跨平台梦还没开始做醒。
真正被改变的是开发者的预期。现在很少有人再相信 "一套代码打天下" 的神话,更多人接受了一个现实:平台差异是客观存在的,框架能抹平的只是表层,底层的性能、体验、系统集成,该花的成本一分省不了。
接下来值得看的是 Google 对 Flutter 的下一步动作。2024 年的裁员潮里,Flutter 团队又传出了人员调整的消息。如果 Google 进一步收缩,Flutter 社区能否维持自治?如果 Compose 3.0 迟迟不来,Android 开发者会不会重新评估 View 体系的寿命?这些问题的答案,比 "Flutter 和 Compose 谁更好" 更值得追踪。
你手头如果有在维护的 Flutter 项目,建议现在开始把业务逻辑层和 UI 层做更彻底的分离。这不是为了迁移到 Compose,是为了不管未来切什么框架,损失都能可控。这种防御性架构,比押注任何一个框架都靠谱。