Flutter 技术调研

Flutter 框架介绍、优缺点、移动技术比较、实践总结、公司可行性建议

Posted by fengs on February 22, 2019

一 概述

1.1 功能介绍

Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android 平台。Flutter 提供了丰富的组件、接口,开发者可以很快地为 Flutter 添加 Native 扩展。同时 Flutter 还使用 Native 引擎渲染视图,能为用户提供良好的体验。

1.2 Flutter 框架

Flutter 框架本身有着良好的分层设计,开发语言为 Dart,Dart 是用预编译的方式编译多个平台的原生代码直接与平台通信,而不需要通过执行上下文切换的 JavaScript 桥接器,避免因为桥接器引起的性能问题。

通过在不同平台实现一个统一接口的渲染引擎来绘制 UI,而不依赖系统原生控件,所以可以做到不同平台 UI 的一致性。

框架结构图.png Flutter 框架

1.2.1 Flutter Framework

  • 底下两层(Foundation 和 Animation、Painting、Gestures)在 Google 的一些视频中被合并为一个 Dart UI 层,对应的是 Flutter 中的 dart:ui 包,它是 Flutter 引擎暴露的底层UI库,提供动画、手势及绘制能力。

  • Rendering 层:这一层是一个抽象的布局层,它依赖于 Dart UI 层,Rendering 层会构建一个 UI 树,当 UI 树有变化时,会计算出变化部分,然后再更新 UI 树,最终将UI树绘制到屏幕上,这个类似于 React 中的虚拟 DOM。Rendering 层可以说是 Flutter UI 框架最核心的部分,它除了确定每个 UI 元素的位置、大小之外还要进行坐标变换、绘制(调用底层 dart:ui)

  • Widgets 层:是 Flutter 提供的的一套基础组件库,包括 Text、Padding、ListView 、ImageView 以及事件处理等。在基础组件库之上,Flutter 还提供了 Material 和 Cupertino 两种视觉风格的组件库。而我们 Flutter 开发的大多数场景,只是和这两层打交道

  • Material 层:根据 Material Design 设计规范开发的 Widget 库。这里的代码都位于 lib/src/material 目录下,里面包含了几乎所有”纸墨设计”规范里面定义的控件。比如 FloatingActionButton、BottomSheet 等。Material 层是使用了 Widget 层的控件来构建的。

  • Cupertino 层:适用于当前 iOS 风格设计下美观且高保真的小组件。

1.2.2 Flutter Engine

  • 这是一个纯 C++ 实现的 SDK,其中包括了 Skia 引擎、Dart 运行时、文字排版引擎等。在代码调用 dart:ui 库时,调用最终会走到 Engine 层,然后实现真正的绘制逻辑

二 Flutter 特点

2.1 跨平台自绘引擎

使用 Skia 作为其 2D 渲染引擎,Skia 是 Google 的一个 2D 图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现,Skia 是跨平台的,并提供了非常友好的 API。Android 系统已经内置了 Skia,但 iOS 系统并未内置,iOS 构建安装包时需将 Skia 引擎置入。

2.2 高性能

  • Flutter APP 采用 Dart 语言开发,Dart 在 JIT(即时编译)模式下,速度与 JavaScript 基本持平。但是 Dart 支持 AOT(Ahead of time),当以 AOT 模式运行时,其运行速度大大高于JavaScript

  • Flutter 使用自己的渲染引擎来绘制 UI,布局数据等由 Dart 语言直接控。布局过程中无需通过 JavaScript 和 Native 之间通信,在滑动和拖动的场景下具有明显优势

2.3 采用 Dart 语言开发

  • 开发效率高。基于 JIT 的快速开发周期,基于 AOT 的发布包

  • 快速内存分配。能够有效地处理小的、短期的内存

  • 类型安全

2.4 热重载

Flutter 最受欢迎的功能之一是其快速,保留程序状态的热重载 (hot reload)。 您可以在 Flutter 应用程序运行时对其进行更改,重新加载应用程序的代码,将其从之前的操作位置继续下去。一次热重载通常用不到一秒钟。如果您的应用遇到错误,您通常可以修复错误,然后继续,就像错误从未发生过。

2.5 丰富的设计控件

一切皆控件,控件是每个 Flutter 应用程序的基本构建块,与分离视图、控制器、布局和其他属性的框架不同,Flutter 具有一致的统一对象模型:控件。一个控件可以定义:结构元素(比如按钮或菜单)、风格元素(比如字体或颜色方案)、布局方面(比如填充)、一些业务逻辑等。

2.6 支持 Windows Mac 和 Linux

三 Flutter 优缺点

3.1 优点

3.1.1 跨平台性

  • 一套代码可以开发出 Android 和 iOS 应用

3.1.2 开发效率高

  • 基于 JIT 的快速开发周期:Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间

  • 基于 AOT 的发布包:Flutter 在发布时可以通过 AOT 生成高效的 ARM 代码以保证应用性能。

3.1.3 热加载

  • 开发原型和迭代更加方便。在应用运行的时候就可以修改代码并重新加载修改后的功能,直接修改崩溃的 Bug,然后继续从崩溃的地方执行调试

3.1.4 可定制的UI组件

  • Flutter 框架本身提供了丰富的 Material Design 和 Cupertino(iOS-flavor)风格的控件

  • 提供了可定制的 UI 框架,不再受制于手机平台控件的支持

3.1.5 良好的兼容性

  • 因为 UI 组件和这些 UI 组件的渲染器是应用程序的一部分,而不是平台的一部分,不需要”兼容库”。降低了在旧版本的测试需求,同时很大可能与未来的操作系统版本兼容

3.1.6 开源

  • Dart 团队与 Flutter 同属 google 旗下,能密切合作,Flutter 团队可以获得更多、更方便的支持

3.2 缺点

3.2.1 Dart 学习成本

  • Flutter 开发依赖 Dart 语言,开发前需掌握 Dart 语言

3.2.2 可读性差

  • Dart 括号太多,嵌套复杂,在逻辑与可读性上表现一般

3.2.3 稳定性

  • 由于 Flutter 刚在2018年12月5日才发布了 1.0 正式版,对其稳定性存疑

3.2.4 安装包大小

  • 与 iOS 原生包比较,在安装包与安装后容量上有明显差距

2.png 安装包大小

3.2.5 启动时长

  • 与 iOS 原生包比较,在启动时长上有差距

启动时长比较.png 启动时长

四 移动动开发技术比较

4.1 原生开发

4.1.1 框架特点

应用程序可以直接与系统通信,以创建 UI 组件或访问系统相机。这些组件被渲染到手机屏幕,而相应的事件则被传回给组件。

框架结构图.png 框架特点

4.1.2 优缺点

优势

  • 可访问平台全部功能(GPS、摄像头)

  • 速度快、性能高、可以实现复杂动画及绘制,整体用户体验好

缺点

  • 平台特定,开发成本高;不同平台必须维护不同代码,人力成本随之变大

  • 内容固定,动态化弱,大多数情况下,有新功能更新时只能发版

4.1.3 代表

Objective-C、Android 和 Windows Phone

4.2 H5+原生

4.2.1 框架特点

应用程序一部分需要动态变动的内容通过 H5 来实现,通过原生的网页加载控件 WebView 来展现。通过一个在 JavaScript 代码和原生代码的”桥梁”进行上下文切换来实现一些访问系统能力的 API。

框架结构图.png H5+原生

4.2.2 优缺点

优势

  • 依靠 H5 动态发布内容

缺点

  • 性能一般,不适用于复杂用户界面和动画效果

4.2.3 代表

Cordova、Ionic、微信小程序

4.3 JavaScript 开发+原生

4.3.1 框架特点

JavaScript 通过”桥接器”访问原生系统。JavaScript 内存中维护了一个 Virtual DOM,JSX(嵌入了 HTML 和 CSS 的元素 JavaScript)内容在 Virtual DOM 中被转化翻译成真实的 DOM树,Virtual DOM 与真实显示的 DOM 保持一一对应。当发生变化时通过 DOM Diff 算法,计算出树种变化的部分,然后只更新变化的部分(DOM操作)。

框架结构图.png JavaScript 开发+原生

4.3.2 优缺点

优势

  • 采用 Web 开发技术栈,社区庞大、上手快、开发成本相对较低

  • 原生渲染,性能相比 H5 提高很多

  • 热更新

缺点

  • 渲染时需要 JavaScript 和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿

  • 由于渲染依赖原生控件,不同平台的控件需要单独维护,并且当系统更新时,社区控件可能会滞后

  • 其控件系统也要受到原生 UI 系统限制

4.3.3 代表

React Native、Weex、快应用

4.4 自绘 UI + 原生

4.4.1 框架特点

通过在不同平台实现一个统一接口的渲染引擎来绘制 UI,而不依赖系统原生控件,所以可以做到不同平台 UI 的一致性。

框架结构图.png 自绘 UI + 原生

4.4.2 优缺点

优势

  • 性能高;由于自绘引擎是直接调用系统 API 来绘制 UI,所以性能和原生控件接近

  • 灵活、组件库易维护、UI 外观保真度和一致性高

缺点

  • 不支持热更新

4.4.3 代表

QT for mobile、Flutter

五 iOS 实践总结

5.1 优点

  • 热加载功能强大,保存即可变动UI展现。在UI微调、出现错误下无需重新启动,即改即得

  • 自定义UI,一套代码可以在 iOS 和 Android 运行

5.2 缺点

  • Dart 代码的嵌套严重,可读性、可维护性差,不熟悉代码情况下无法及时定位组件位置。开发组内需定义开发规范,布局习惯、注释等

  • 在 UI 界面不符合预期时,无法同 Xcode 一样分析 UI 层次结构

  • 会明显增加应用包体积(需内嵌 Skia 框架)

  • 第三方库还不够丰富

5.3 实践感想

  • Flutter 一切皆控件(Widget),需格外熟悉各个控件

  • Flutter 只支持纯代码编写 UI

  • Flutter 断点调试情况下会进入框架代码

  • Flutter 框架部分继承 iOS 开发思想,在导航栏跳转、布局间距等细节上与 iOS 雷同

5.4 Flutter 混合开发

  • 原生工程需添加配置文件,指向 Flutter 动态库

  • 通过 “xcode_backend.sh” 编译工程

  • 修改 AppDelegate 类

  • 通过路由 “Route”、渠道 “Channel” 实现原生与 Flutter 交互

六 公司项目可行性说明

Flutter 开发的应用在性能上接近原生。Flutter 提供丰富的组件、接口,开发者可以很快地为 Flutter 添加原生扩展。Dart 开发效率较高,基于JIT 快速开发(热加载)节省了开发时间,基于 AOT 的发布包可生成高效 ARM 代码保证了应用性能。跨平台自绘引擎 Skia 确保多UI展现统一,一套代码多端运行,这样带来的经济效益也较明显。

在技术储备方向上 Flutter 也大有所为,随着谷歌下一代全平台操作系统 Fuchsia OS 的不断发展,Flutter 作为其用户界面框架也必会越来越流行。

公司项目应用上可酌情引入 Flutter 进行混合开发,应在 Dart 语言学习、原生与 Flutter 交互、第三方库切换上多考量。

参考资料