本文由 简悦SimpRead 转码,原文地址 shift.infinite.red
*...在所有不重要的方面。
*......在所有不重要的方面。
Artwork by Jenna Fucci
Flutter和React Native作为两个最常用的多平台移动应用框架,是天然的竞争对手。争论不休......开发者争论不休......最后,应用程序被运出,使用其中的一个或另一个。
那么哪个更好呢?
聪明的答案,也就是高级工程师们会厚着脸皮说的那个答案是。"这取决于。两者都有优点和缺点,最终这是一个关于权衡的决定"。
但这很难是一个令人满意的答案。这就像说NBA中最好的球员是 "取决于他们的角色"。这并不能刺激脱口秀的炒作,推动点击率,并增加参与度
所以,让我们来制造一些戏剧性的事件,激怒一些人,并讨论为什么Flutter比React Native更好......_在所有不重要的方面。
什么是重要的?
我们可以讨论所有不重要的事情:性能、开发者体验、Dart与JavaScript、本地集成、标准库,还有很多很多。
这个标题很有煽动性;我会给你这个机会。但是,这篇文章并不是单纯的点击诱饵 事实上,我将在本文后面以更细微的方式深入探讨这些事情中的大部分。
但让我们切入正题。什么是重要的?
答案根本不在于React Native和Flutter的技术方面。它甚至不是一个移动开发者可能关心的东西。
但是对于那些决定下一个应用使用什么的人来说,这才是现在最重要的。
Hiring
现在,招聘开发人员是出了名的困难。技术人员的工资在上涨,而供应量却有限。找到愿意为你的公司工作的合格开发人员就像拔牙一样。
Flutter的开发人员充满激情,质量很高--这绝不是在给Flutter开发社区抹黑!他们只是没有......。他们只是不......高 量。这并不像你有一个巨大的Dart开发人员的池子可供选择。你总是在培训,几乎每个人都在雇用。
另一方面,React Native开发者有一个巨大的池子可以利用,那就是JavaScript社区。到目前为止,JavaScript(及其流行的变体TypeScript)是世界上最流行的编程语言,并且仍在快速增长。支持React Native的React.js可以说是世界上最大的编码框架之一(如果不是 唯一)。它仍然很难被雇用,但可供选择的开发人员的数量远远大于Flutter。把一个React开发者变成一个有合理生产力的React Native开发者是一个简单的过程。
分享代码、知识和开发人员
虽然招聘是决定使用Flutter或React Native的最大、最有影响的部分,但还有一个非常重要的部分我应该提到,那就是分享代码、知识和开发人员。
有什么比好的代码更好?更少的代码。而拥有更少代码的最好方法之一就是在多个应用程序之间共享代码。它可以减少你的初始开发时间并简化长期维护。
很有可能,你的公司正在使用React.js,或者至少是JavaScript,在其网站、网络应用程序、服务器等方面。能够在你的React.js应用、Node服务器等之间共享代码是React Native的一个巨大的超级能力--而Flutter在这方面还没有那么强。
除了分享代码,能够在你的网络、后端、iOS和Android团队之间分享知识也是一个巨大的优势。你可以有共同的维基,Slack频道,等等。而且网上有大量关于React Native、React和JavaScript的教程、博客文章、StackOverflow问答等等。
当然,你也可以在这些项目之间分享实际的开发人员,并且能够在一个关键项目上增加人数,而不必重新培训几乎所有的人。
最后,在React Native和Flutter之间做出选择时,很难超越这些绝对关键的因素。
其他方面呢?
但是......性能如何呢?开发者体验如何?可访问性、第三方库生态系统等方面如何?
在几乎每一种情况下,Flutter和React Native都不相上下。Flutter赢得了一些战役,React Native赢得了其他战役。在任何特定的技术领域(除了与网络共享代码,如上所述),都没有一个框架是绝对的胜利。
就这样了。这就是这篇文章。你可以停下来了。你得到了重点。
好吧......你为什么还在读?
那是什么?你想知道具体细节吗?细节?
Gant Laborde告诉我,当你坚持着陆时,不要再跑。当你完成销售时,就停止销售。
但我无法控制自己。我喜欢谈论商店。
让我们深入探讨一下。
开发者经验
Flutter的团队(以及谷歌总体上)在开发者体验方面相当出色。
为Flutter开发设置环境通常比React Native容易。Flutter的热重载通常比React Native的快速刷新效果好。他们有一些非常好的工具用于调试、剖析和检查你的小部件树。他们内置的端到端测试比React Native的Detox好很多。Flutter的CLI是一流的--例如,我真的很喜欢他们的flutter doctor命令,你可以直接从CLI管理你的模拟器和仿真器。
Flutter也有更好的升级体验,因为你只需在现有的应用中运行flutter create,它就会在新版本中重新创建一切。
另一方面,React Native的工具缺乏Flutter的工具所具有的大量抛光。React Native的升级体验是一个比较痛苦的方面,任何在过去几年中使用过它的人都会证明这一点。
它正在得到一些改善;在最近的React Native Radio插曲 (RNR 227)中,我们与来自微软的几位开发者谈论了他们为改善React Native的工具和整体开发者体验所做的工作。
此外,Expo旨在极大地改善React Native的开发者体验,通过Expo应用服务,你现在几乎可以在Expo中做任何你在vanilla React Native中可以做的事情。Expo的升级体验非常好,他们的集成工具也非常好用。如果你不使用自定义的原生代码,Expo Go应用是一种很好的方式,可以在不编译的情况下快速与他人分享构建。Expo是一个非同小可的优势--如果你在使用它的话!
TL;DR:Flutter的开发者体验是其最有力的主张之一。React Native正在迎头赶上,还有一段路要走--但Expo给了它强大的助力。
性能
很难比较任何软件框架的性能,更不用说像Flutter和React Native这么复杂的东西了。Flutter和React Native在大多数情况下都 "足够快",特别是当有能力的开发者对它们进行了性能优化之后。
但从历史上看,Flutter的开箱即用性能一直比React Native的好。也就是说,你当然可以把性能差的Flutter应用和性能非常好的React Native应用一起写。
性能差异主要是由于异步的React Native桥,随着新架构在今年春天的推出,它将被本地和JS之间的并发通信所取代。此外,Hermes JS引擎提高了很多关键指标的性能。最后,Skia现在将进入React Native,这意味着你可以在React Native中使用与Flutter相同的渲染器--但仅限于你需要那种流动画布性能的地方。
TL;DR:Flutter在性能上略胜一筹(目前),但随着新的React Native架构的推出,这一差距将很快缩小。
统一UI体验
Flutter 使用 Skia 渲染其 UI,并在所有平台上统一其外观和感觉。这让他们可以优化性能,并在不受平台基元限制的情况下做自定义UI。
另一方面,React Native在iOS上使用UIKit,在Android上使用Android的布局系统,在Web上使用DOM。这意味着,虽然你可以建立非常相似的应用程序,但它们将被每个平台的解释所影响。
对Flutter的一个批评是,它必须重新发明各种平台已经基本解决的问题,比如可访问性、字体缩放等等。公平地说,他们在这方面做得相当好(通过使用较低级别的内置平台钩子),但这是他们必须重新实现的另一件事,而React Native或多或少可以依靠平台原语来提供。
值得注意的是,谷歌的开发者曾表示,统一的体验不再是核心目标。这似乎与Flutter的方法不太吻合。
TL;DR: 如果你接受这样的前提,即在一个平台上符合用户的期望比拥有一个统一的体验更重要,那么React Native在这一点上胜出。
原生集成
与原生平台的集成是我在直播流中最喜欢做的事情之一(快速插播--查看我的Twitch流并点击那边的Follow!)。
Flutter将Dart代码编译为原生代码,并使用他们所谓的平台通道与原生代码进行了相当酷的整合。它允许同步的本地调用,并允许你用Swift和Kotlin编写。Flutter的文档在这里真的很好。他们给你所有的工具,你需要测试和模拟这些开箱即用。你会得到很多适合每个平台的模板,并且通过Isolates对线程有一流的支持。
在React Native中,与本机集成有一点学习曲线。(这就是我建立React Native Colo Loco的原因之一--让这种体验更美好!) 更不用说要应对React Native桥的限制了。本机集成的文档也不太理想。
值得注意的是,新的React Native架构将取代桥接,并为React Native带来原生同步集成的所有优势,这确实缓解了其中的一些不足。
TL;DR:两个平台都有完整的原生集成能力,但Flutter的原生集成工具更好。
国际化
国际化/本地化(i18n)绝对重要,Flutter带有内置的i18n支持,而不是依赖第三方的支持。然而,React Native的第三方i18n支持最近也变得相当不错。Mazen Chami和我最近做了一个直播在应用中实现RTL语言支持(阿拉伯语)。
TL;DR:没有优势--两个平台的国际化工作都做得很好,尽管仍然存在一些限制。
内置的导航(及更多)
Flutter的设计比React Native更 "包含电池",其中一个最明显的方式就是它自带了自己的导航/路由器解决方案。
导航是一个特别适合集成到核心框架中的模块,因为它对大多数应用来说都是非常关键的。例如,想象一下没有自己的路由器的Next.js吧。只是......没有那么有用。
React Native就没有那么多意见了,它允许你带来你自己的导航解决方案。有很多,但支持最多的是React Navigation和React Native Navigation库(不幸的名字)。
Flutter还内置了主题支持等。Ignite,我们的非常受欢迎的React Native模板,有它自己的主题支持,但主题支持不是React Native内置的。
拥有像Flutter这样的内置解决方案的好处是,它们可以被专门调整,以便与框架的每个版本良好地配合。像Flutter这样的内置解决方案的缺点是,当一个更好的范式出现时,要想让官方支持的解决方案换成更新、更好的解决方案,可能需要一个上帝的行为。
TL;DR: Flutter的优势。有一个内置的导航器是很好的,但是React Native的社区提供了一些非常好的选择。
网络支持
Flutter 2宣布了对网络和其他平台的支持(Robin Heinze和我在React Native Radio上对它进行了评论)。
但他们对网络的态度是 "让我们使用画布并在上面画画",而不是使用本地DOM。Sebastien Lorber在这个Twitter话题中更详细地介绍了这一点。
这带来了可访问性和SEO问题。它还要求......好吧,你用Flutter做网页,这并不是每个人的首选,说起来很温和。
值得注意的是,Flutter确实提供了一个HTML/CSS/DOM版本。它比画布渲染器用得少,即使如此,它也无法与React.js目前的情况相提并论。
另一方面,React Native可以直接分享代码,无论你是使用React Native for Web还是直接使用React.js。你可以使用JavaScript/TypeScript共享服务和模块来共享大量的业务逻辑、数据模型等,而将UI组件分割开来或使用React Native for Web直接共享。React.js是专门为网络设计的,因此网络是一流的公民,与Flutter for Web不同。
如果你想对Flutter进行批评,包括它对网络的支持,请查看Theo最近关于这个问题的YouTube视频和Luke Pighetti对Theo视频的反应,他不同意Theo关于Flutter移动端的很多结论,但对Flutter for Web大致同意。
TL;DR:React Native的明显优势。虽然Flutter 2正在朝这个方向发展,但React Native在Web方面有巨大的领先优势,似乎不太可能放弃。
第三方程序库
在一个典型的React Native应用中,我们使用了许多最初为JavaScript或React设计的库和工具。其中包括axios, mobx, redux, lodash, ramda, eslint, babel, jest, prettier, react-devtools, typescript, npm, and yarn。
这些都是Web和Node开发者经常使用的库。这意味着联合社区可以贡献和改进这些工具,以及(再次)分享知识和相互帮助。
另一方面,Flutter通常使用专门为Flutter设计的库。一些第三方的Dart库是可用的,但这个社区比JavaScript小得多。
说到这里,值得注意的是,Dart有一个统一的格式化、测试、编译器、分析器/linter和包管理器,是一种类型安全和空安全的语言。这意味着在使用Flutter和Dart时,你可能需要更少的第三方库。
TL;DR:Flutter和Dart有一些高质量的内置工具,但第三方生态系统是React Native的优势,因为在Dart/Flutter这样一个孤立的社区,几乎不可能复制像JavaScript/React这样强大的生态系统。
使用React Native与Flutter的公司
React Native现在确实是一个多公司的努力。除了Meta/Facebook,微软也对React Native的发展进行了大量的投资。核心团队在React Native的各个方面与微软开发人员不断合作。他们在微软用React Native重写了许多应用程序,并为其建立了大量的工具和库。事实上,他们甚至最近宣布,Windows中的主要设置应用(部分)是用React Native编写的!
除了Meta(Facebook和Instagram)和微软,React Native还被Coinbase、Shopify、Mercari、Discord、Pinterest、Tesla、沃尔玛、Wix、Salesforce、NFL、MLS、Uber Eats等大公司广泛使用。
Flutter主要由谷歌支持,谷歌对其产品的长期支持记录参差不齐(最好是)。还有一些其他公司在使用Flutter,包括丰田、eBay和阿里巴巴,但大部分的发展是由谷歌推动的。
说到这里,Flutter在开放性方面做得很好,完全开源,由社区的持续参与和反馈驱动--这与React Native的普遍感觉不同,React Native首先由Meta/Facebook的需求驱动,并在最终对外提供之前私下完成。React Native的核心团队最近一直在努力使这个过程更加由社区驱动。
TL;DR:React Native的优势,还有一些额外的细微差别,无法用一句话概括。
动态更新(代码推送,等等)
这并不适用于每一个项目,但我听说很多公司选择了React Native,因为它能够进行动态更新,而不需要提交给App Store和Play Store并通过审批程序。这是Flutter的不在路线图上。
TL;DR:React Native的优势。
那么,你应该使用React Native而不是Flutter吗?
嗯......这取决于。两者都有优点和缺点,最后是一个关于权衡的决定。
尽管在这个问题上已经洋洋洒洒写了几千字,但即使是这里提到的差异也不是那么巨大或明显。
正如我所提到的,有一个更大的开发人员池可以雇佣是首要考虑的。如果你已经有使用JavaScript/TypeScript的Web和后端开发人员,当然_特别是如果你已经在使用React,React Native就特别有吸引力。
如果你是一个Java或Android商店(如果你来自Java/Kotlin,Dart更容易)和/或需要更多的统一的流体UI,Flutter当然是一个可行的选择。它可能更难雇用,但Flutter卓越的开发者体验和性能是相当不错的安慰奖。
最后,"这要看情况 "的应对措施确实是一个正确的答案。但是,至少你现在有了更多的信息,可以知道你在做什么权衡了。
其他想法
任何提出这种有争议的主张的文章都将不可避免地受到严格审查。这是我的观点,鉴于我拥有一家React Native咨询公司并与React Native核心团队合作,我不会声称自己没有偏见。然而,我已经做了相当多的研究,与许多公司合作,考虑到这两者,并将这篇文章交给几个Flutter开发人员,并得到他们的反馈。他们可能不同意我的观点和结论,但他们的反馈肯定被考虑到了,并在适当的地方加以实施。我想尽可能的公平。
我也尽量不关注美学上的东西,比如Dart与TypeScript的语法,或者JSX与Dart的widget层次结构。我们可以整天争论哪个更好,但这些纯粹是个人偏好,不会对框架的可用性产生任何实际影响。并不是说Dart和JavaScript/TypeScript之间没有区别--是有区别的--但要解决这一系列特殊的权衡问题,可能需要另一篇2000字的文章,而这已经超出了我在这里的范围。
最后,如果你想阅读一篇有理有据的反面观点,Isaac Lyman的Stackoverflow博客上的文章是值得一看的!
我很感谢几个人给我的反馈,帮助我测试我的假设,并分享他们自己的观点。并非所有的人都希望他们的名字印在这里,但还是要感谢你们。
感谢。
- 我的商业伙伴Gant Laborde一如既往地提供了令人敬畏的建议和编辑工作--尽管我忽略了他的一些最好的建议,这是我自己的危险。
- Mike Diarmid提供了一些很棒的反馈,特别是在本地集成部分和开发者经验部分。
- JD分享了他在自己公司几个月来比较RN和Flutter 2的经验
- 来自Ping Labs的Theo关于这个主题的令人难以置信的严厉视频。
- Luke Pighetti对Theo的视频和文章的反馈做出了有理有据的反应
- Robin Heinze,感谢她的洞察力和校对。
- 安德鲁-加布里埃尔提供了极为有用的反馈意见
- Derek Greenberg的校对和建议及鼓励
- Jenna Fucci为她在本文中提供了惊人的定制艺术。
- 还要感谢:所有 "喜欢"我的原始推特并强迫我写这篇文章的人。你们这600多个混蛋。;-)
有反馈吗?请在Twitter上联系我: https://twitter.com/jamonholmgren
This post has been translated into Korean.