简单说一下
回答中我觉得可以商榷的地方:React Native 基于 JS-Native Bridge 的渲染方案有着没有办法弥补的先天缺陷。性能上优化到 60 fps 都比较成问题,更不用提以后广泛普及的 120 fps 的设备。
RN 之前的桥是完全异步的,JS 线程并不会阻塞 UI 线程的 vsync。
对于普通的动画场景,RN 17 年发布的 Animated API[1] 实际上是让 JS 线程对动画「声明式」的做一个「描述」,然后序列化后扔过桥一次就好,帧与帧之间的刷新都是 UI 线程直接跑原生实现,并不需要「过桥」,所以刷新率什么的并没有什么影响。
可是问题在于,有一些强交互的场景(比如跟手拖拽)就需要同步阻塞更新怎么办?这才到了我今天真正想聊一下的「RN 新架构」。RN 在 18 年就提到了原有的桥架构不支持同步调用的问题[2] ,所以新架构(Fabric,FB 已经全量在用了)是依赖 JSI (JavaScript Interface)而非桥来做通信与远程调用得。相关的资料比较零散,很多都在各种 youtube 视频或者社区博客上(我随手搜到了一篇对社区文章的中文翻译[3],尽管我觉得原文有的地方也不太准确……)。
不过简单得说,新架构的做法类似大家常见的宿主环境(浏览器/Node)向 JS 引擎提供原生对象/方法的做法,是一种链接时的 FFI,所以不但支持同步调用,而且通信不需要序列化/反序列化,可以直接类型安全地和 JS 引擎的堆内存互操作,这带来的性能的提升大概是两个数量级得……而且你会发现新架构中 JSI 的两端都是 C++, Yoga 布局引擎是 C++ 外,核心的跨平台模块(比如 shadow tree)还是 C++。这一套零成本抽象下来怎么会虚你区区 Dart 带着个 GC 和 RTTI 的 AOT?
Flutter 的设计则是完全自绘组件,Skia 渲染引擎本质上就相当于游戏引擎的作用
Skia 是 Chrome/Android 都在用的二维图形库,Flutter 像个游戏引擎是真的。
从跨平台的 UI 一致性的角度上看,Flutter 可以做到完全的一致性,而 RN 在点击效果,阴影,甚至文本框之类的组件都无法做到不同平台间有着完全一致的行为。这点上对于有跨平台一致性强迫症需求的人来说,Flutter 几乎可以说是唯一选择。
Flutter 做得像游戏引擎有图形表达力强以及 self-contained 的优势,但是对于跨平台开发来说就「仁者见智」了,「完全的一致性」真的是我们想要的吗?iOS/Android 本来就有着不同的设计语言(滚动效果、点击效果、系统 UI 组件),有不同的 distribution 版本,并且也会不断演化。
你没看 Flutter 为了「模拟」原生效果只好搞了两套所谓的「平台物理」……然后系统 UI 组件还要全部自己造一遍主题轮子吗……Flutter 的 iOS 主题美其名曰 Cupertino,结果人家 Cupertino 真的改一版设计,你的轮子一下老了一代又要重新画了委屈不委屈?(其实现在的看起来就挺过时挺惨得……)要不是你们 Mountain View 钱多人多真的烧不起……
RN 的哲学之一就是 be native,所以才用了 binding 的方式,Cupertino 一声令下我们 Menlo Park 只要重新 build 或者重新 binding 一下 API 就好……这种做法可以很好的融入平台,方便复用以往的基础设施,而且非常容易拓展:RN 的 Windows 和 macOS 版本都不需要重新自己「画画」,而且还是大 Redmond[4] 做得呢……RN web 也是社区(Twitter)维护起来的,直接 binding 到 DOM 就完事了,跟以往的 web 基础设施在一起工作毫无问题。
而且你也看到了,RN 是真正的开源社区活跃,而 Flutter 就比较「吃 Google 饭」了……天哪你知道 Flutter 砸了多少人进去,RN 才多少人吗?只能说 Google 真的钱多,像 Flutter 的 Hummingbird(Web Support)要做起来真的是一件相当吃力不讨好的事情,真的钱多。
当然如果仅从个人小项目,对于性能要求不苛刻的情况下,确实 TypeScript 比较 Dart 还是有一些语言上的优势,对于前端开发者来说可能更好上手一些。
虽然理论上 Dart 很容易性能更好,Dart VM 也很有实力。但是我从来没有看到过任何像样的数据可以证明「哦 Dart 性能确实比 JS 好」,欢迎拿数据打脸。
但 Dart 语言由于有丰富的语言特性(比如 extension)
你认真得?Dart 是要特性没特性,要品味没品味……要不是劈柴砸钱 Flutter 这玩意早凉到不知哪里去了。以前怎么从没见人用呢,Flutter 一出来你们反倒吹起语言来了?
参考
- ^Using Native Driver for Animated https://reactnative.dev/blog/2017/02/14/using-native-driver-for-animated
- ^State of React Native 2018 - Architecture https://reactnative.dev/blog/2018/06/14/state-of-react-native-2018#architecture
- ^React Native 架构演进 https://zhuanlan.zhihu.com/p/142704512
- ^https://microsoft.github.io/react-native-windows/