1. Flutter 原理与优势

在开始之前,先简单了解一下 Flutter:

image.png

我们可以看到 Flutter 框架包括 Framework 和 Engine,他们运行在各自的 Platform 上。其中,Freamwork 是 Dart 实现的,其提供了基础 Widgets 与 渲染、动画、绘制、手势等能力,开发者可以基于此实现各种 Widgets;而 Engine 是 C++ 实现的,包括 Skia 二位图形库、Dart VM、Text 文本渲染等。实际上,Flutter 的上层能力都是由 Engine 提供的,Flutter 正是通过 Engine 将各个 Platform 的差异化抹平,从而保证多端一致性。接下来,我们自上而下逐一分析 Flutter 的优势。

1.1 Framework (Dart)

首先,我们看看 Framework。其实,Flutter 选用 Dart 语言作为上层语言也是绝妙的选择。

在语言设计上,Dart 的设计目标应该是同时借鉴了 Java 和 JavaScript。Dart 在静态语法方面和 Java 非常相似,如类型定义、函数声明、泛型等,而在动态特性方面又和 JavaScript 很像,如函数式特性、异步支持等。并且 Dart 又各自取长补短从而完善自身,语言特性上丰富且优雅。

并且 Dart 运行时和编译器支持 Flutter 的两个关键特性的组合:

  • 基于JIT的快速开发周期:Flutter在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;(注:这一点客户端开发同学应该深有体会,手 Q iOS 开发同学和我说改动一行手Q代码都要编译40分钟才能看到效果)
  • 基于AOT的发布包: Flutter 在发布时可以通过 AOT 生成高效的 ARM 代码以保证应用性能。而 JavaScript 则不具有这个能力。

至于 Dart VM 的性能方面,我想我们也不需要太过担心,虽然没有找到相关测试数据,但毕竟 Google 在 Go(没用 VM 但有 GC)、JavaScript(V8)、Dalvik(Android 上的 Java VM)上已经有了很多技术积淀,事实上 Dart 开发团队的很多成员都是来自 Chrome 团队的。

1.2 Engine(C++)

其次,我们看看 Flutter Engine 的优势。之前我们无论是开发 React Native 还是 Hippy 的混编项目,UI 组件的渲染实际上都是交由 Native 侧负责渲染的,这就会导致可能存在的多端不一致性。下面分别 Hippy iOS 工程的代码结构、Hippy 与 Native 的通信原理与 UI 组件渲染过程图(出处:@dahonglin 同学的 《iOS Hippy 实践》分享,React Native 原理图与 Hippy 一致,此处不赘述),Hippy 侧调用某组件,实际上通过 JS Bridge 是向 Native 请求渲染 Native 提供的组件,渲染工作由 Native 自己完成,而非 Flutter Engine 直接提供 Render 能力来抹平多端的差异性。

image.png
image.png
image.png

1.3 Platform(Native)

最后,这一层我们主要来关注一下 Flutter Plugin 与 Native 的通信。Flutter Plugin 可以提供通过 MethodChannel 调起客户端 API 从而使 Flutter 获取客户端能力,原理如下所示:
image.png
比如我们可以封装一个获取剩余电脑的 Plugin,在 Dart 侧直接使用两端封装好的 API 即可。
image.png

综上所述,Flutter 是 Google 使用 Dart 语言开发的一套移动应用开发框架,它不同于其他开发框架:

  1. Flutter 使用 AOT 预编译代码为机器码,所以它的运行效率更高**,**且运行时采用 JIT 模式,支持 Hot Reload。
  2. Flutter 的 UI 控件并没有使用底层的原生控件,而是使用 Skia 渲染引擎绘制而成,因为不依赖底层控件,所以多端一致性非常好
  3. 开发者可以通过 Plugin 与 Native 进行通信,扩展性也非常强