Flutter 和 RN、Weex 等跨平台技术相比有什么优势?


flutter的技术没有什么革命性的地方。

但是flutter确实是工程和市场性做的最平衡的东西。也只有google有这能力。

需求就是一次开发: 所有端能用。

市场性比flutter好的:react native。可以复用一堆javascript/css程序员。无缝开写。但工程型差很多。一次写完

到处适配。android和ios还好。但是以后的web端。各种屏幕端?还有性能问题了?

工程性比flutter好的:Qt。但是问题就是不会有人用C++写业务了。

所以。你觉得技术上没有比已有的技术好是对的。觉得用dart不尊重市场也是对的。但是放在一起就是比其他现有解决方案要好。


并没有,在我看来就是flutter就是谷歌对着浏览器砍了一大刀而砍出来的东西.丢了许多的包袱.


Flutter是谷歌的移动UI框架,它可以快速的为iOS和Android构建高质量的原生UI。 当前被越来越多的开发人员在使用Flutter。Flutter有四大主要特性:

第一.Flutter具备一个高性能的系统架构,Flutter的代码最终会被编译成原生的ARM代码执行。

第二. Flutter有很好的开发体验和开发效率,特别hot reload(热重载)的功能,它可以让等待代码编译的情况成为过去。

第三. Flutter自带了整套的material design组件库,以及主要的iOS系统组件,可以帮助开发者快速的构建他们的移动应用,同时可以达到美观和可用的效果,

第四. Flutter的同一代码库,可以同时部署到iOS跟Android两大移动平台,帮助开发者节省开发和部署的时间。

开发人员都知道,开发一款能够让用户真正喜爱的应用是非常难的,有四个重要的点需要考虑:

  1. 快速,无延迟的触摸反馈。应用程序的速度必须快,不能够有延迟,这是最基本的要求,
  2. 响应用户快速变化的需求。应用程序的功能和用户界面是应该不断迭代,以满足用户变化的需求和市场的情况。
  3. 自然易用。移动应用必须要容易使用,它需要尊重各个平台上用户已经形成的使用习惯。
  4. 美观有表现力,UI设计要能够表现一个品牌的特点,让用户能够过目不忘,这样才能够在非常激烈的市场竞争中脱颖而出。

Flutter框架就是希望帮助开发者能够更好的解决上述这几项挑战。

第一.快速,无延迟的触摸反馈

Flutter通过两点来保证一个移动应用做到高性能无延迟,首先Flutter的代码不论在Android还是在iOS上,都是编译成原生代码执行的。FlutterSDK有两个部分组成,它有一个引擎和一个框架。Flutter代码引擎是由c和c++代码编写,在Android上通过ndk编译成原生代码,在iOS上通过llvm编译成原生代码,然后Flutter框架本身由dart语言编写,当部署到生产环境的时候,dart代码会通过aot(ahead of time)的方式编译成原生代码执行。

其次,Flutter在架构上保证了执行的高效率,它的一个技术特点是它不调用系统自带的UI组件,以此来降低应用程序代码跟平台之间的通信造成的性能损耗。

Flutter和react native有明显的区别,下面是一张用Flutter写的应用程序和用react native写的应用程序,分别和操作系统的通信的需求和机制的图。

上半部分是flutter应用和操作系统的关系,下半部分是react应用和操作系统的关系,大家可以看到flutter应用,它只用移动操作系统提供的画布,其余的ui渲染过程都是在自身的应用程序代码和flutter本身的框架的代码来完成。这样的架构不但在性能上存在优势,同时也让开发者对整体的ui可以深度控制,可以控制屏幕上的每一个像素。flutter架构上的特点,让它能够在型号比较老的手机上也能够达到每秒60帧的性能。

第二.响应用户快速变化的需求

其次flutter能够帮助移动开发者快速响应用户的需求,这一点对于中国的开发人员特别重要,因为中国的互联网发展速度是全球领先的,flutter有几个特点可以帮助开发者实现快速的产品迭代。

flutter代码编译速度非常快,

上面的漫画是一个非常经典的关于程序编译时间的梗,开发人员可能也体验过编译项目可能要等一分钟或者几分钟,才能把一个很小的ui反映到你正在运行的APP上面,flutter中有个功能叫做hot reload,它能帮助开发者节省不必要的等待时间,让整个开发体验更加流畅。 Hot reload不仅仅可以用到比较小的ui改动上,如果你对uI的布局做了一个大的改动,它也可以在几乎不到一秒的时间,把这个更新体现到你正在运行的移动应用上面,

Hot reload还有另外一个优点,就是会保持这个应用的当前状态,所以当改变这ui中的颜色啊字体大小的时候,ui上的数据是没有被重置的,移动应用还是当前那个状态。这个特点对于开发导航流程非常复杂的移动APP是特别方便的,因为不需要再执行一遍流程到你当前改动的那一页,然后每改动一点,又要重新走一遍流程或者输入各种用户数据。除了hot reload之外,flutter还自带了丰富的widget(组件),帮助开发者迅速实现原型,并且进行迭代。flutter自带了大量高品质的material design组件,同时flutter也提供基本的iOS 系统组件,让你的应用符合iOS用户的使用习惯。

还有就是flutter能够帮助开发者实现快速迭代的开发,支持在iOS跟Android上同步开发和测试。这里举个例子,有一款应用为百老汇音乐剧汉密尔顿制作的。哈密尔顿在美国是一个非常非常火爆的百老汇音乐剧,他们用flutter开发了一款同主题的移动应用,在iOS和安卓上都同时发布,并且受到了广泛的好评。这款应用其实在发布前一周是出现了一个问题,就是汉密尔顿的团队发现首页的设计会产生很大的问题,他们想对首页进行大改,但是离发布只有一个礼拜,在传统的开发方式下,这样开发时间是无法完成任务的,然而意外的是一周以后他们如期发布了这款应用,是在实现了所有他们他们想对首页设计做出改动的情况下,汉密尔顿的主要的开发者前段时间召开的GDP欧洲大会上分享了他们的体会,他说如果当时在两个平台上有两套不同的代码。是不可能在应用发布前一周,那么短的时间内,如此大幅度改动首页ui。

第三.自然易用的ui

前面介绍flutter其中一个特点是能够帮助开发者实现快速迭代产品,一款优秀的移动应用程序是应该尊重用户的基本使用习惯,而不是让用户需要去学习那些非常底层的操作,跨平台设计的目标是在展现品牌特色的同时要做到尊重系统平系统平台的设计特点。 flutter框架对于作为一个同时支持iOS和Android两大移动平台的SDK,flutter可以实现这两个平台上用户使用很自然的用户体验,首先flutter对系统的ui的最底层的基本的交互实现了自动的匹配,开发者不需要多写一行代码就可以实现这些匹配,flutter框架还提供了两套不同风格的ui组件,如果你的应用需要进一步跟操作系统的风格保持一致,你可以选择在不同的系统上显示不同风格的系统组件。

第四.美观有表现力

最后flutter为了实现在iOS和Android两大平台上让用户感觉自然的用户体验,就是flutter可以帮助开发者实现高度定制的有品牌表现力的uI设计。这一点非常重要,如果大家关注最近这几年获奖的应用程序,会发现大量的应用都不是一个简单的系统风格的设计,这里举一个例子,一个应用叫做breakfast,他们获得material design award,这款应用设计并不是简单的安卓风格或者是iOS风格,有属于自己的品牌特色的设计,应用中有大量的定制化设计,这是移动应用设计的一个趋势,为了适应这样的趋势,flutter做了很好的支持。flutter可以帮助开发者实现高度定制的uI设计,它希望是开发者可以不再对uI设计师的想象力说不。现实中有uI设计师可能有时候也会碰到这样的问题,ui设计师有一个很好的想法,当把想法告诉开发人员,然后开发人员告诉你是不是有一点想多了,这是一件多么尴尬的事情,希望以后不会再出现。Flutter希望在框架的层面帮助大家充分发挥自己的创造力。

通过下面架构示意图了解flutter如何在技术层面上可以保证ui的可定制性,

flutter框架是由很多层组成的,最上面一层是material design widgets和cupertino的位置,也就是苹果风格的系统ui组件,一方面开发者可以直接使用最上层的两套有ui控件来快速实现接近系统标准风格的应用uI,另一方面开发者也可以通过使用较低几个层次的组件,或者通过组合不同的高层次的组件来实现高度定制的uI,并且整个framework都是开放源代码的,所以非常容易让开发者了解每一个组件是怎样实现的,并且在上面做进行修改。

在每一个flutter应用程序里面,每一个像素都是由flutter框架和引擎本身绘制的。不受限于系统本身提供的ui控件,所以开发者对于它的应用程序的外观和交互都是有一个全局的控制能力。

在这里在总结以下flutter的主要的特点,首先flutter具备一个非常高性能的系统架构,保证应用程序能够流畅的运行,其次flutter有优秀的开发体验和开发效率,再次就是flutter有一个美观非常丰富的,并且是可扩展的组件库,最后flutter可以用一个代码库来编译成iOS和Android的移动应用,帮助开发人员提高开发效率,快速响应用户的需求。


Flutter 的革命性在于它亲爹是 Google,技术上没有革命性。

什么代码热更,代码推送,自绘组件,别的跨平台 UI 框架很多早都有了,甚至跨的端还比 Flutter 多,举个例子:Xamarin(含Xamarin.Forms),支持开发Windows(UWP/WPF)、Linux(GTK#)、MacOS、iOS、Android、tvOS、watchOS以及WebAssembly这么多的GUI应用程序,可以说只要是有显示屏的设备就没有不能用Xamarin的时候。

然而在国内,只要是 Google 的东西,无论东西到底如何,

刚一发布公告就一大堆人吹跨世纪的创新;

刚一发布 beta 就一大堆人吹稳定好用可生产环境;

刚一发布正式版就一大堆人吹 IT 界的革命。

其他家的东西尤其是 Microsoft 的,哪怕东西再好,

发布的时候无人问津;

发布的时候甚至连篇 blog 介绍都没;

发布以后问起来用都没用过就说不咋样。

也不看看谷歌历史上多少东西都是刚一出来贼火,火过一阵子就挂了。轮砍东西 Google 可是不输 Microsoft 的。

Dart 语言你以为是新的?根本不是。谷歌推了好几年了,一开始出来呀各种新闻,但是因为太难用所以后面根本没什么人用,前几年一度还差点死了,现在借助 Flutter 好不容易让 Dart 看势能捞一波。你们以为这是个什么好东西?觉得好用的怕不是 Java 写多了见怪不怪了。

native 跨平台 UI 框架想要真的做好离不开对方平台的官方支持。然而事实是 Apple 推 Swift、Microsoft 推 Xamarin,Google 推 Flutter,每家都想在这个领域分一杯羹,还轮不到别家过来在自己平台上搞一手。

好用和能用之间差了十万八千里远,Flutter 不出所料至今为止只有对安卓的支持是最好的,而就算是自己亲儿子安卓也一大堆的 bug,其他端体验真的只是“能用”。这不是什么亲儿子不亲儿子的问题,而是没有别家的支持你是根本做不起来的,幻想着 Flutter 统一各平台 UI 开发真的就是想屁吃,就包括更成熟的 Xamarin 在内也是在想屁吃,不然你觉得为什么 Xamarin 发展了这么多年结果用的最多的是用它写 UWP,也有一些安卓,iOS 几乎没人用它开发。

我寻思着跨平台 UI 框架未来也就只能通过非 native 的方式来曲线解决了,比如 electron,比如 webassembly。要 native?原生,请。


虽然我对 Flutter 的使用评价相当正面,但这个问题下很多尬吹实在很难看下去。它们就像是说「美国诞生了工业革命」一样令人尴尬……

我们来逐条看一看,有哪些对 Flutter 自身「革命性」的赞扬属于张冠李戴吧:

  • 解决 reflow 问题的高效单向布局算法」——这跟安卓里那个「先跑一趟 measure,再跑一趟 layout」的经典操作有本质区别吗?在安卓 View 的 measure 阶段,就完全是「父节点向子节点传布局约束,子节点向父节点返回宽高尺寸」这么一回事呀。
  • 既能 JIT 又能 AOT」——别的不说,早在 2014 年,Java 在安卓上就能用 AOT 编译的机器码替代 JIT 了。这说法同样明显忽略了谷歌自己过去的技术成果,扛着红旗反红旗啊。
  • 超越 React Native 的声明式 UI」——恰恰相反,相比起 React,Flutter 的 Widget 机制是为性能牺牲了易用性的,典型例子就是 StatefulWidget 在 API 设计上的令人困惑之处。个人认为这地方说难听点都快属于抽象泄漏(Leaky Abstraction)了。因为它没有隐藏 build 机制的复杂性,还把下层的 Render Tree 直接通过 BuildContext 暴露给了 Widget Tree。
  • 极强的可扩展性」——Flutter 本身完全基于 Skia 绘制,如果想嵌入一些外部的平台 UI,在开发成本上是明显高于带有 Native Module 的 React Native 的。好在现在 PlatformView 得到了推广,并且 Dart VM 也开放了动态链接 API,情况有所好转,但相关的文档和社区实践仍然较为匮乏。后面有机会我可能会单独写篇文章介绍一下后者。
  • 能做游戏」——虽然确实可以,但 Flutter 整个框架根本不是为游戏场景去优化的,大量工作都是为了更好地渲染传统的 UI 界面,从而实现局部刷新、渲染缓存、长列表、流式排版等能力。举例说来,UI 场景是非常强调局部刷新的。假如某个静态页面中有个 GIF 在放,那么 Flutter(以及所有的浏览器引擎)都能保证每帧只有那么一小块地方会重绘。而游戏引擎可不会管这么多,因为游戏几乎每帧像素都不一样,要画下一帧的时候直接全量重绘就好。它们的优化方向一般是「如何支持大量同屏物体运动」之类,放着不动也会持续逐帧重绘,耗电量很感人的。所以「Flutter 的革命性在于能做游戏」这种说法就像是说「杜蕾斯的革命性在于可以套在枪管上防潮」一样,人家设计出来可不是用来让你套在这里的……
  • Dart 语言」——Dart 本身的语言特性有什么革命性的地方吗?去看看前一段时间推出的 10 Years of Dart 吧。这里面负责 Dart VM 的 Vyacheslav Egorov 多次表明这就是个照着经典理论来的的工程实现(当然引擎做得好也是很不容易的)。

注意上面澄清的这些问题,其实都确实是 Flutter 自己的「特性」,但不是它原创的「革命性的特性」。在这点上相信没什么好继续抬杠的吧。

但是俗话说得好,既要防止左,也要警惕右。这个问题下更离谱的是一个拿 Xamarin 来贬低 Flutter 的匿名高赞回答,踩一捧一这套玩得很熟练嘛。按罗翔老师的说法,一根手指指向别人,四根手指就指向自己。既然一定要对线,我们就来数一数 Xamarin 自己有哪些问题吧:

  • 仍然是 RN 的思路,在 iOS 和安卓上都得用 C# 写特定于平台的代码,没有利用好 C# 生态里的 SkiaSharp 去从底到上地绘制 UI(话说 SkiaSharp 这东西是真的神奇,我对 Skia 很多用法的了解反倒都是在 SkiaSharp 社区查到的)。
  • 基于 XAML 的经典 MVVM 设计思想,还是十年前(Xamarin 在 2011 年推出)的产物,在 React 组件化思想普及的今天已经落后了。支持声明式嵌套组件(Widget)的框架设计优于严格地把布局和逻辑分离开(区分 XML 和 JS)的设计,这早就是前端社区的共识了。
  • 开发期的 Hot Reload 平台限制多多,而且只支持 XAML 代码,对 C# 业务逻辑无效,跟 Flutter 的方案不是一个量级的东西(后面会提到)。
  • C# 和 Visual Studio 不管对 iOS、安卓还是 Web 开发者都非常陌生,官方甚至从来都对自家的 VSCode 不管不顾。你看看 Flutter 可是暗渡陈仓,同时兼容了前端爱用的 VSCode 和移动端必备的 Android Studio 呢。在批判「谷歌动辄始乱终弃抛弃开发者」之前,能不能自己先照照镜子?

如果你稍微认真看看 Xamarin 的架构图,就能看出它其实就相当于一个 C# 版的 React Native:

如果图不够,这里还摘录了一句微软文档的原文:

Xamarin.Forms allows developers to create user interfaces in XAML with code-behind in C#. These user interfaces are rendered as performant native controls on each platform.

我不是说 RN 式依赖平台控件的架构不好,它们各有所长。但光是这一点,就足以反驳匿名回答里「Flutter 除了背靠 Google 以外一无是处毫无创新,里头全是 Xamarin 早就做出来的东西」这种信口开河的观点了。

说实话,我是非常反感「Flutter 能火反映了中国程序员无脑跟风追随 Google(的低劣民族性)」这种话术的。你看难道 Xamarin 在国外就很火吗?

回到正题,个人认为 Flutter 确实有这么几个具备很大突破的地方:

  • Flutter 真正意义上把简化的浏览器引擎打到了 App 里,彻底解决 UI 控件的兼容性问题——这和游戏引擎的做法类似,但要知道实现「从管理 OpenGL 的纹理 Buffer 到排版复杂的的 UI 布局再到配套应用层语言的运行时与开箱即用的工业级 UI 组件库」这么一大堆东西,传统上从来都是 OS 厂商的职责,以前任何一个第三方的移动端跨平台技术团队,都没有足够的资源和技术积累来挑战这件事(我知道的应该只有桌面端背景的 Qt 吧,但它拿 C++ 作为业务开发语言太劝退了),只有搞浏览器出身的这批人敢。
  • Flutter 切实地通过 Hot Reload 解决了传统移动端开发的效率问题。这是需要框架团队和语言引擎团队紧密协作,联手投入大量工作的。如果你看过 Dart 团队的分享,会发现他们非常关注所谓的 Development Cycle,也就是从修改完代码到看见反馈的这个周期——这个周期必须越短越好!为此 Dart VM 为 Flutter 量身定做了很多重大特性,典型之处就是把解释器的 parsing 过程拆分到 PC 端,每次修改代码后,只增量地编译并传输二进制的 AST 数据(.dill 文件)到设备上。这种重度侵入性的设计使我在尝试「把 Dart VM 从 Flutter 里抽出来单独使用」的时候遇到了不小的麻烦,但好处也很明显,那就是 Flutter 不管是 Hot Reload 还是 Hot Restart,都很难遇到那种被大型单体应用编译速度拖累的问题,还能在 AOT 模式下具备高性能。
  • Flutter 在开发者生态上,找到了 App 团队和前端团队之间的双赢点。成功的 Hybrid 架构落地,离不开两种背景的开发者协作。而至少在我们这里,作为协作者的 App 团队总体是认可并愿意投入资源到这种架构的(相比之下对于很多「根红苗正」的移动端背景技术负责人来说,RN 的性能问题和碎片化兼容问题一直有争议,移动端团队踩到坑很可能就想给你换回去)。而前端团队从 JS 换到 Dart,并不会比从 Vue 换到 React 更难。不过这里讲下去肯定多少涉及一些非技术层面的问题,就不展开了。

如图所示,为保证极速加载的开发体验,Flutter 拆分了经典的「词法分析-语法分析-解释执行」过程。它先在 PC 端编译 Dart 源码为二进制 AST,将其通过 RPC 协议增量发送到设备上,动态替换掉受影响的 Library 后执行重绘,整个过程中应用的运行时状态保持不变。当然原有状态可能失效,这时需要 Hot Restart。

诚然,Flutter 很多地方缺乏理想中的精致性,不少细节处的 API 都需要你绕一下然后拼起来。但这里讨论的不是某种单一的语言特性,而是工作流,是技术栈,是解决方案的投入产出比!个人感受是,作为一套应用开发技术栈来说,Flutter(在我们的场景下)不管是 Dart 在语言特性上相比于 TS 和 Kotlin 的劣势,还是 Widget API 的嵌套写法相比于 JSX 的不便之处,都是相对次要的、非决定性的、可权衡接受的——当然切记这要具体问题具体分析,不是在跟你布道啊。

哦对了,既然是在知乎,那怎么能忘了这里的财富密码呢?Flutter 最大的革命性当然在于,它可是已经支持全场景分布式微内核的鸿蒙 OS 了哦!其实说起来在安卓和 iOS 上,我都抽离搭建过 Flutter Engine 里的 Skia 上下文初始化过程。基于我自己的经验,个人认为这篇介绍如何将 Flutter 移植到鸿蒙的文章,其叙述是严谨可靠的。全文亮点很多,特别是这一句非常有风度:

由于鸿蒙……在很多基础概念上与 Android 有相似之处,我们可以从 Flutter 的 Android 版实现入手,完成对鸿蒙的移植。

差不多了,这篇回答的跨度有点大,最后做个总结吧:

  • Flutter 当然是具备革命性的。但夸要夸对地方,不然看起来像低级红高级黑。如果你是工程负责人,要从系统的角度去分析评判框架,不要浮于复读公关稿和表层 API 这种层面的东西。
  • 不要凡是见到国内流行的东西就鄙夷,这多少有点「逆向民族主义」的味道。多想想这不是世界范围内的普遍现象,别人是不是也这样,程度如何。
  • 当你熟悉的框架不受主流认可时,首先应该反思它为什么干不过人家,为什么会变成冷门,而不是靠着这个小众性来孤芳自赏地(匿名)彰显优越感。


推薦閱讀:
相关文章