[Flutter翻译]Flutter vs. React Native。哪个才是适合你的跨平台框架?

286 阅读15分钟

本文由 简悦SimpRead 转码,原文地址 stackoverflow.blog

构建传统的本地应用程序通常需要维护两个或更多的代码库。让我们看一下两个......

我最近和另一个行业的朋友一起做了一个应用原型。白天,我是一个针对桌面和移动网络的全栈开发者,但考虑到这个应用的使用案例,我们确定它需要全功能的离线。对于网络开发者来说,有几种传统的方法来提供离线体验。

  1. 渐进式网络应用程序。通过添加清单文件和服务工作者,一个响应式的网络应用程序可以快速转换为在没有互联网连接的情况下加载的东西。它是否真的能工作是另一回事,真的取决于网络应用的构建方式。通常情况下,围绕数据缓存、同步、冲突解决和离线请求处理要做的事情比简单地使你的应用成为PWA要多得多,而且在一天结束时,你仍然不会有一个应用在两个应用商店中。为了让它显示在某人的主屏幕上,用户必须访问网站并点击屏幕底部的安装按钮,这是一个不熟悉的操作,而且违背了大多数用户的肌肉记忆,即在任何涵盖网站内容的地方刷掉或点击X。我对PWA的未来寄予厚望,但现在我不认为它们是接触用户的一种有效方式。
  2. CordovaApache Cordova通过将网站放入WebView(基本上是本地应用的iframe),并将WebView打包成iOS或Android应用,从而将网站变成移动应用。虽然这是迄今为止将网站带到应用商店的最便宜的方式,而且理论上可以完成几乎所有原生应用可以做的事情,但根据我的经验,这并不是无摩擦的。这个过程和最终结果都充满了令人不快的惊喜。即使是一个在移动浏览器中完美运行的网站,也可能需要大量的工作才能在Cordova应用程序中看起来和感觉正确。此外,对本地智能手机API的支持是不完整的,有时是不可靠的;即使是像媒体控制这样简单的东西,实现起来也是令人沮丧的。因此,尽管Cordova作为提供 "应用中的网站 "的最具成本效益的方式发挥了重要作用,但我认为它并不是一个新项目的最佳选择。(在这里我不能不提到Ionic,它确实有助于实现原生的外观和感觉,但通常需要部分或全部重写,而且仍然不能解决我提到的很多问题。)

在排除了这些选项之后,我所知道的其余选项是。

  • 传统的本地应用程序
  • Xamarin
  • React Native
  • Flutter

构建传统的原生应用需要我维护两个或更多的代码库,而且我还要从头开始学习Swift,所以这听起来比我报名的时候要麻烦。Xamarin可能是一个不错的选择,因为我在日常工作中使用.NET,但我的印象是,它没有其他公司那样强大的社区和市场份额。我也有一些相关的经验可以考虑。我已经用React做了几个副业,并且一直在用Flutter做一个游戏。最后,React Native和Flutter似乎是我技能组合的最佳选择。

在几个周末的时间里,我做了两个概念验证的应用程序,分别用React Native和Flutter的最新版本。我并不打算写我的经验,我只是想做一个简单的应用程序的原型,但比较结果是非常有趣的;这是两个完全不同的框架,每一个都有其令人沮丧和愉快的方式,我认为从一个网络开发者的角度来比较和对比它们是很有价值的。

我并不期望自己能完全不偏不倚。我对Flutter的体验比对React Native要好得多。然而,我将尽力公平对待它们,并承认它们各自的优点和缺点。

它们是如何工作的。组件和渲染

React Native(由Meta/Facebook创建)提供了一套React组件,代表布局和UI抽象,如视图(用于包含和安排元素,像一个div,上面有display: flex)或TextInput(像一个HTMLinputtextarea)。然后,它使用一个C++引擎,为每个平台单独编译,将这些翻译成本地组件,在屏幕上渲染。你的代码通过一个JavaScript引擎运行(目前是JavaScriptCore,Safari使用的引擎,但一个名为Hermes的自定义引擎可能很快就会接管),并通过桥上的序列化消息与本地代码进行通信。

Flutter(由谷歌创建)是一个集视图框架、渲染引擎、代码执行引擎和组件库于一身。它使用Dart,一种由谷歌创建和维护的高级编程语言,并明显受到React的启发:每个部件(组件)都有一个构建(渲染)方法,通常返回一个或多个其他部件的树。Flutter不在目标设备上渲染本地组件,而是选择接管整个屏幕并渲染自己的用户界面(与视频游戏不同)。你的Dart代码是为桌面和移动设备使用的各种指令集提前编译的。在网络上,它被转换为JavaScript。

你可能认为为Flutter学习一种新的编程语言所需的时间会比设置和学习React Native工具的时间多出一个数量级。然而,我完全没有发现这一点。Dart是一种非常简单且对开发者友好的语言,与TypeScript、C#和Kotlin有很大的相似之处。它的文档是一流的。更重要的是,我很喜欢学习它--它的可读性极强,有很多很酷的特性,比如级联符号默认的空安全,而且编译器很会告诉你哪里出错了。因此,是的,你需要花一天左右的时间来学习这门语言,但如果你已经知道强类型的命令式编程语言,你会很容易做到的。

使用React Native,只要你知道JavaScript或TypeScript,你就不会花时间学习新的编程语言。然而,你将不得不学习一些标准的工具和库来提高速度--感觉React Native的工具和生态系统要比Flutter复杂得多,但在质量上并没有真正的优势(下一节将详细介绍)。对我来说,这两个框架的升级时间是差不多的,比较一下我第一次学习Flutter(通过Flame,一个游戏开发库)和学习React Native的时间。我估计,无论哪种方式,提高生产力的最低时间都是10到15个小时。

我承认,我的情况不一定是典型的。市场上精通React的开发者比任何形式的Dart都多,所以在很多商业场景中React Native可能更有意义。但是对于你自己的项目,不要让Dart的障碍阻碍你。

功能。没有比第一次聚会更好的聚会了

React Native遵循标准的Web开发方法,其特点是你的本地node_modules文件夹。它包括你拥有一个应用程序所需的基本工具,但如果你想要一个UI语言(如Material DesignCupertino)、图标、状态管理、本地化、HTTP请求、高级开发者工具等等,你将依靠社区支持的代码或编写自己的。这并不一定是件坏事。React Native社区很大,而且非常活跃。但这确实意味着一个典型的React Native应用将是由代表不同设计理念的软件包、非标准化的API和一知半解的文档拼凑而成的。

相比之下,谷歌在过去几年里对Flutter进行了大量投资,并支持开箱即用的令人印象深刻的功能集。Material Design和Cupertino组件、数百个图标、基本的状态管理设置、几个运行时的开发者工具和25个核心的第一方包,包括本地化、HTTP请求等等--所有这些都有树形摇动,所以你不会用你不使用的东西使你的应用程序膨胀。我所使用的组件都有一个一致的设计,并且像手套一样适合这个框架。你可以在完全没有任何第三方包的情况下发布一个强大的、设计良好的Flutter应用,这在React Native中是不可行的。我在React Native中的package.json文件和Flutter中的pubspec.yaml文件之间的大小差异是惊人的。Flutter只是做得更多。

或者,我应该说,它做的更多是现成的。Dart的软件包库,pub.dev,可能永远不会接近NPM的规模。考虑到NPM没有访问浏览器或Node API,很难估计有多少NPM包与React Native兼容,但我猜测还是有足够多的包可以在数量上取胜。

如果你对自己编写不常见的算法或视觉效果的能力有信心,你可能会对这两个框架都很满意。否则,你会想在开始之前在每个软件包库里打探一下,看看它们是否有你需要的东西。

UI。平台、一致性和定制

在使用Flutter和React Native时,我在让我的UI在不同平台上看起来都一样时遇到了一些麻烦。Flutter有自己的图形引擎,所以你会认为无论你去哪里,一切都会是一样的。但我确实注意到在网页、MacOS和iOS输出之间的间距和对齐方式有一些差异,但我无法修复。虽然它们是非常小的、单一像素的差异--我怀疑最终用户甚至会注意到--但它们确实让我有点紧张。

由于React Native在每个平台上渲染原生组件,它几乎不可能比Flutter有更少的一致性问题。果然,在一个星期天,我花了大半天时间对我的电脑大骂,因为一个应用栏在网络上运行正常,但在iOS上却消失了,而且调试器崩溃了,没有任何有用的错误信息。这个问题最终是我的iPhone 12模拟器、我使用的第三方设计库和一些自定义样式之间的问题的交集。我还没有在Flutter中遇到过如此难以捉摸的问题。

说到样式,React Native使用CSS。它比这稍微复杂一些,但如果你对CSS(以及重要的是,flexbox)很熟悉,你就可以在React Native中随心所欲地使东西看起来像你想要的。Flutter的造型机制虽然不同,但也不是完全陌生的--大多数类似CSS的属性都是由同名的部件字段表示的,而Column和Row部件是flex布局的直接替代物。不过,你可能还是要查一下你想做的每一件事,或者偷看小部件的代码,而不是插入一些CSS属性,然后继续你的快乐之路。Flutter的组合范式也需要一些时间来适应;很多你通常可能用CSS属性应用的东西在Flutter中都有自己的小部件。

这两个框架都是非常可定制的。如果你有像素般完美的设计,你会很快进入构建组件的状态。

性能。响应式用户体验和动画

Flutter的最大卖点从一开始就是速度。该框架的营销演示充满了全面的全屏动画,不会错过任何一帧。而且,从我用它构建一个简单的游戏的经验来看,我可以证明它有能力处理你扔给它的东西。它很流畅。事实上,我之所以转向Flutter,是因为我已经厌倦了在HTML5画布上看着精灵在屏幕上闪动和交错。

这并不是说Flutter会比本地应用更快。即使性能在视觉上与原生应用相似,你仍然有一个完整的非原生渲染引擎在硬件之上运行。至少,你会使用更多的内存。

React Native在性能方面并没有什么优势。它在后台解释JavaScript,然后在JavaScript引擎和原生代码之间扮演中间人。我们已经知道JavaScript是相对较慢的。这给它增加了一个全新的翻译层。

也就是说,两者的速度都是足够快的。我不建议用这两种软件来构建一个沉浸式的第一人称射击游戏(尽管Flutter无疑会处理得更好),但这不是你来这里的目的,不是吗?当我们在谈论文本表单和商业逻辑时,没有必要为十几或二十几毫秒的响应时间争论不休。作为一个程序员,你所做的决定对用户体验的影响要远远大于引擎盖下运行的框架。

有一点需要注意的是动画。Flutter团队一直在努力使他们的框架成为美丽的、触摸响应的动画的代名词。如果你想建立一个用涟漪和花纹包围用户的应用程序,Flutter就是你的首选。

管线。构建和发布您的应用程序

也许阻止React Native开发者跳槽的最大原因是Expo。Expo是一家私人公司,为React Native应用提供开发者工具和服务,包括一个可管理的跨平台运行时间、本地API模块和一个用于两个应用商店的自动部署工具。Expo还提供了一个名为Expo Go的应用程序,让你可以在智能手机上测试你的应用程序,而无需侧载或使用有线连接;只需将你的相机对准生成的QR码,你就可以了。这是一个令人印象深刻的产品。

Flutter并没有相应的服务。有fastlane,它填补了发布自动化部门的一些空白,当然Flutter也有一个内置的跨平台运行时间。但是如果你想在实体智能手机上测试你的Flutter应用,你必须把它插入你的笔记本电脑,然后移动一些.apk或.ipa文件(或者让你的IDE为你移动它们)。Android和iPhone都有很好的第一方模拟器,所以你不一定每天都要这么做。但这不如使用Expo Go方便。

开发者的经验。身处战壕

这一部分将比其他部分更加主观。我相信很多开发者都喜欢React Native的体验,也有很多人对Flutter感到沮丧。但对我来说,Flutter比React Native更容易使用和工作,这很可笑。有几个客观因素对Flutter有利--快速重载、更紧密的VS Code集成和更广泛的内置调试工具--但我不能说这些都是决定性因素。

我的概念验证应用包括一个应用栏,一个可点击的瓷砖列表,一个带有一些数字输入的表格,一些方程式,以及一个输出表。我以前从来没有在这两个框架中建立过任何这些东西。

我在React Native中构建的时间是Flutter的两倍。

其中大部分时间都是在为一些基本的事情伤脑筋:项目设置、图标、我之前提到的消失的应用栏、神秘的CLI警告、让受控输入工作。因为我先建立了React Native应用,所以我可以复制和粘贴一些东西来节省Flutter应用的时间。但当我回顾这次经历时,时间上的差异甚至不是最突出的。而是我对React Native几乎一直感到沮丧,对Flutter几乎一直感到高兴。Flutter总是有我需要的东西,而且效果很好。React Native指给我一个NPM包和一个Stack Overflow答案,然后说 "祝你好运"。

同样,这是我自己的经验。我相信随着时间的推移,我会习惯于React Native的怪癖,并发现我不喜欢Flutter的东西。但在我的脑海中,我想在未来使用的东西是毫无疑问的。Flutter,每次都是。

你的里程会有所不同。对于另一种观点,Jamon Holmgren的文章赞成React Native绝对值得一读。而Fireship的对比视频提供了一个平衡的视角,涵盖了我在这里谈到的许多相同的观点。

摘要:最好的框架是你使用的那个

如果你正在寻找一种流畅的、集成的开发者体验,撇开所有的商业影响不谈,我对Flutter的推荐是不无道理的。但最近React Native阵营有很多令人兴奋的消息,它在更容易的招聘和大规模开源社区支持方面为自己提出了强有力的理由。有足够多的嗡嗡声;今年的Stack Overflow开发者调查显示Flutter和React Native并驾齐驱,RN在 "专业开发者 "类别中略微领先,Flutter在 "所有响应者 "类别中略微领先。(两者都远远领先于Ionic、Cordova和Xamarin)。

客观地说,这里没有明显的赢家。你会根据你的应用程序的需求和限制来选择一个框架,就像你做任何技术决定那样。React Native显然不会消失,一年后,由于社区贡献的稳定步伐,开发者的体验可能会大大改善。但在我看来,Flutter将继续存在,并将在短期内大幅增长,因为开发者发现它是多么强大和容易使用。

标签。Flutter, react native


www.deepl.com 翻译