798a9eda503947c25f3066fac9febe14
再谈 Flutter

一个月前,因为头条准备接入 Flutter,我简单的调研了一下。当时写了一篇总结:谈谈我对 Flutter 和 RN 的看法。总结来说就是比较看好 Flutter,也参与了早期 Flutter 项目的搭建过程。

随着项目一期的灰度上线,我得以抽出一定的时间回顾这一个月来的研发过程,并且做出下个双月的规划。随着对 Flutter 了解的加深,我开始重新思考一个问题:“Flutter 真的是一个优秀的,值得 all in 的跨平台方案么?”虽然技术一直在发展,但是多思考这类问题,有助于我们更加清醒,更加高瞻远瞩的看待技术。

Flutter 不像是个正常工程师写的库

首先谈一谈表面现象,正如标题所说,Flutter 不像是正常工程师写的库。它有一些非常搞笑,非常低级的设计问题:

  1. Issue 数量只增不减。截止我写作时,Flutter 的 issue 数量 已经达到 3848 个,并且我很看好它突破 4K。而作为竞争对手之一的 React Native,仅仅 653 个。Issue 的数量侧面反映出团队的维护热情,和项目的质量。作为一个内部开发了两三年,又对外公开了半年,甚至已经 Prelease 了好几个月的库来说,实在是不应该。
  2. 莫名其妙的 Bug。比如有一段时间, 就算你按照官方的文档,也无法把 iOS 的 Demo 运行起来,后来发现原因是底层某个正则表达式写错了,导致无法识别本机的 IP 地址。这种低级错误出现在 Flutter 上,还带来这么大的影响,实在是无法忍受的。
  3. 极为外行的设计。Flutter 的很多工程设计,在我看来也就是大学生水平。比如 flutter attach 命令在我的电脑上可以运行,在同事电脑上就不行。浪费一晚上后才发现,它要求项目根目录里一定要存在 build 文件夹,内容不重要,但一定要存在,否则就报错。再比如它的运行日志是直接输出到工程目录下的,如果你不配置 gitignore,项目就会被搞得一团糟。最最匪夷所思的是,如果想把 Flutter 和已有 Native 项目结合起来,必须修改 Flutter 源码才行,因为源码里面写死了项目名称必须是 Runner。以后每换一个项目,还得再改一次源码。

Flutter 的优势真的是优势么

相比于 React Native,Flutter 主要的优势在于,它提供了一套绘图引擎,也就是跨平台的 UIKit,来保证一套代码在两端的展示效果是一样的。

但仔细想一想,Flutter 的优点,也就是 UI 样式在双端展示的效果强一致,真的是我们在乎的么?我倒不这么认为,主要是有以下理由:

  1. 用户对双端 UI 不一致是有预期,而且可接受的。安卓的 Material Design 和 iOS 的扁平化风格本来就不一致。国内的产品和设计为了简单,有时候也直接使用 iOS 的风格。而且也不会有用户闲着没事,拿两个手机玩找茬游戏。
  2. 以 React Native 为例,刚刚说了同一个组件在双端效果不一致并不是问题,但如果某一段的功能有 Bug,就需要单独修复了。这才是 Flutter 真正解决的问题,但平心而论,这种需求很多么?解决这种需求花费的时间很多么?我看是一个值得讨论的问题。
  3. 我个人认为,相比于 UI 风格的问题,更多的问题还是出现在在与 Native 的适配上。比如已有的几乎所有客户端组件,都需要写一个 Bridge(Flutter 中的术语叫 Plugin,为了方便大部分同学理解,我统一叫 Bridge)。而且随着双端客户端组件的不断迭代,Bridge 也需要迭代。因为很难要求 Native 组件的维护人还会 Flutter,所以不得不抽调专门的同学,同时了解 Native 组件的业务逻辑和 Flutter,并且长期参与迭代维护,这会消耗大量的人力。
  4. Flutter 的设计很美好,用来写新的 App 是毫无问题。但一旦集成到已有项目中,必然会和 Native 产生强耦合。比如安卓和 iOS 的导航栈实现方式不同,就需要双端各自适配。再比如现在硬件五花八门,每种硬件特性也要适配。虽然每个功能的适配看起来都是小问题,但万万不可低估无数个小问题叠加起来以后,对长期维护带来的影响。不是有句古话说的挺好么:“路远无轻担”。

同时我们不能忘了,Flutter 的缺点也很明显:

  1. 不能热更新
  2. 不能实现前端需求
  3. Dart 生态不够成熟,学习成本高

在我之前的调研中,我把 Flutter 定义为一个 替换 Native 开发 的方案,所以倒也不在乎前两个问题。第三个问题是被我低估的,我一直觉得这种新的语言和工具,学习下就可以了。但是站在团队角度,还是要考虑下投入产出比的。以做一个双端需求为例:

原来:iOS 1人力 + 安卓 1 人力,基础设施齐全
现在:Flutter 1.2 人力(这真是很乐观估计了,学习成本在很长一段时间内不会消失),因为踩坑或者适配 Native 组件,iOS 0.4 人力,安卓 0.4 人力,最后还是 2 人力。

这还是在尽量复用 Native 已有设施的情况下的统计,如果还想统一一下,用 Dart 来实现,绝对会投入更多的人力。以我们上个双月的进度来看,一共投入四个人力做 Flutter,也只不过是解决了最基本的的问题,勉强能上线而已。距离做到完美,还需要以年为单位进行投入。

top Created with Sketch.