简介: Flutter 是开源的 UI 工具包,其能够帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。Flutter 组件采用现代响应式框架构建,中心思想是用组件 (widget) 构建 UI。淘宝终端技术部无线技术专家王康从 Flutter 的原理出发,介绍了 Flutter 的原理、业内现状,以及阿里巴巴在 Flutter 上所做的深度实践和探索。
一 Flutter 原理
Flutter 主要有四个特点:美观、高效、高性能、开放。
- 美观:Flutter 提供了丰富的 Widget,比如动画、手势等。Flutter 采用了组合式 API 模式,因此为 UI 创建带来了更强的灵活性。此外,Flutter 使用了游戏引擎的方式来写 APP,使得用户可以具有很强的灵活性,能够在像素级别进行控制。
- 高效:Flutter 类似于安卓小系统,使得其能够使用一套代码运行在各种各样的平台之上。此外,在 Debug 模式下还支持热重载,使其能够达到高效的研发效率。
- 高性能:在 Release 模式下,Flutter 是预先编译成机器码,执行期具有高性能。
- 开放:Flutter 是一个开源的项目,基本所有工作都可以在 GitHub 上看到。
以上四个特点的背后就是 Flutter 的原理。首先,Flutter 架构在 OS 之上,最底下是与平台相关的 Embedder 层,其主要负责的工作是 Surface、Thread 以及 Event Loop。在 Embedder 层之上是 Engine,主要包括三部分,Dart Runtime;负责将 UI 绘制到 Surface 上的 Skia,负责文本绘制的 Text。在 Engine 之上就是大家所熟知的 Dart 的 Framework。基于上述这些,开发者即可开发应用。
阿里巴巴为什么选择 Flutter
在阿里巴巴的电商场景下,往往会有一些非常重要的考量,比如用户体验的要求,对于研发效率的要求,以及如何消除多端之间的差异。在阿里经济体里面,应用所需要部署的目标设备是非常多元的,不仅有常见的 iOS 和 Android,还有钉钉等桌面场景、天猫精灵等 IoT 场景以及各种线下大屏的场景。当前,流量增长红利不断减少,需要更多创新玩法为消费者提供更好的用户体验,这就产生了富交互游戏化的需求。Flutter 具有的高性能,高研发效率、跨端一致性,多端多平台支持,以及丰富的表达力使其可以解决这些痛点。
二 Flutter 业内现状
在阿里巴巴内部,目前有十几个 BU 的几十个产品正在使用 Flutter,典型的包括淘宝、闲鱼、UC 以及优酷等。在业内,腾讯的微信、Now 直播、翻译君等,字节跳动的西瓜视频、皮皮虾,快手的快影,美团的美团骑手、美团外卖商家版、美团众包以及百度的贴吧等也都应用了 Flutter。
Flutter 在业内的实践现状主要围绕着体系化、深度、框架以及更多探索这些维度展开。在体系化方面,需要做一些基础设施的建设,这是因为 Flutter 以及 Dart 的很多东西还不成熟。使用 Flutter 解决业务上线问题,需要考虑研发体系的构建。应用上线之后,需要监控各种指标。在深度方面,往往会关注引擎大小、包大小、内存优化以及启动时间等。除了上述两部分之外,业内也有很多框架相关的工作,比如混合栈框架、状态管理、动态化 UI、AOP 框架以及生态插件等。此外还有原生 Flutter 以外的一些探索,比如小程序渲染和前后端一体化等实践。
三 AliFlutter 建设与深度实践
AliFlutter 业务实践
下图选取了阿里经济体中一些应用了 Flutter 的典型场景。比如宝贝详情是一个业务逻辑非常复杂的页面,属于图文混排的页面,并且具有大量图片,有时还包括一个视频播放器,在这个场景下就全部应用了 Flutter。有团队使用 Flutter 框架用于游戏业务的开发,比如下图所示的是盒马使用 Flutter 构建的一个游戏页面。此外,在 Alibaba 这一应用中,也大量使用 Flutter 用于构建主链路以及订单页面等。
之所以选择 Flutter,有几个典型原因。首先,HotReoload 和跨端一致性使得研发非常高效;其次,可用于游戏化的丰富 UI 表达力、动画、图文混排性能等诉求都能被 Flutter 很好地满足。
AliFlutter 业务研发模型
在业务场景的背后是 AliFlutter 的业务研发模型。其实,Flutter 本身主要解决两个问题,逻辑和 UI。其本身没有各种 Native 能力,需要为其补齐如网络、推送以及接入网关等,使其更加接近于业务开发容器,而不仅仅是 UI 开发框架。再上面就是应用开发框架,比如状态管理框架、游戏化框架、动态化 UI 以及组件库,在此之上就可以构建一些业务了。除此之外还会涉及到一些研发协同方面的工作,比如打包构建、Linter、Pub 库等。
AliFlutter 引擎研发模型
在 AliFlutter 之下,存在很多引擎修改的场景。举例而言,在 iOS 13 以下可能存在一些后台 GPU 渲染 Crash 的问题,在 Android 上存在特别机型 Flutter 启动闪退的问题。此外,还需要考虑如何让 Flutter 和目前已有生态进行融合,比如图片库、网络库等在阿里内部都有比较好的实践。无论是 Bug 修复还是 Native 能力提升,其实都是对于 Flutter 引擎所做的定制化工作。
上图展示的就是在阿里内部对于 Flutter 引擎进行定制所做工作的逻辑,首先通过 Flutter 框架获取对应的引擎代码,拉取依赖,进行开发,到 Gitlab 做 CI,代码审核完成之后将产物构建出来上升到服务上面,最终通过简单的方式来提供服务。
AliFlutter 基础设施建设
自定义引擎服务
前面所提到的是自定义 Flutter 引擎的开发流程,而想要将开发完成的东西提供给其他人使用,就需要如下图所示的自定义引擎服务了。对于 Flutter 开发者而言,只需设置一个环境变量去服务上查询是否有对应的产物即可,如果有的话,就做一些定制并返回给开发者;如果没有则去官方上游拉取。当然了,对于 Flutter 的基础设施而言,需要有一些多团队的支持,比如 Namespace 等机制。最早的时候,阿里巴巴通过 Git 方式管理自定义引擎,但是 Git 对于二进制很不友好,所以就使用了高效自定义引擎服务来解决问题。
私有 Pub 服务
除此之外,AliFlutter 还实现了私有 Pub 服务。最初的想法是将不同人开发的库等工作归类组织起来,建设更好的内部生态,实现更好的复用。Pub 本身就是 Flutter 所提供的开源框架,但是其深度绑定了谷歌云服务,所以在做这部分的时候需要将对于谷歌云的依赖变成对于阿里内部的依赖。主要工作分为两部分,一部分是对于包的简单管理和存储,这部分可以通过阿里云存储 OSS 实现;还有一部分是监控包的下载量以及健康程度等,这部分还部署了 Meta 数据库服务,在将包上传的时候将数据同步过去,以及面向使用者的前端服务。
持续构建
这部分的主要工作就是如何将所写的 Flutter 代码提供给没有 Flutter 环境专门用于打包平台。Flutter 工程可以通过一些脚本构建出一个 Pod 或者 Gradle,进而集成起来变成一个 APP。
AliFlutter 深度实践
图片库优化
在阿里巴巴内部,除了对于 Flutter 做的一些体系化实践,还有不少深度化实践。比如对于图片库的优化,对于 Flutter 而言,本身的图片库存在一些问题,比如内存占用高,不释放问题、CPU 占用问题。为了尽可能遵循 Flutter 原生的图片库逻辑,做了图片库的优化。主要工作包括对于 Flutter 框架的整体修改,能够较好地实现一致性,与官方体系无缝融合,对接内部图片库,其在性能以及易用性上面也具有较好的表现。
引擎大小优化
我们在 Flutter 引擎大小优化方面也做了不少工作,简单介绍对于库的裁剪。如下所示的两张火焰图,其较好地表达了 Flutter 引擎所依赖的各个库裁剪前后的比例对比。裁剪后的内容既保证了功能的完备性,也显著降低了引擎大小。
大图片内存 GC 优化
除了前面所提到的类似于音频图片释放等内容之外,阿里在实践的过程中发现 Flutter 在大图片内存 GC 方面存在一些问题,比如在用户退出的时候内存无法得到很好释放。对于社区中使用 Flutter 的同学而言,面对这样的问题建议大家在 Profile 模型下看下点击了 GC 按钮是否能够将内存降低下来。基于此逻辑我们提供了一套供上层业务使用的 GC API。从 FlutterEngine 开始依次调用 Shell、Engine、RuntimeController 以及 Dart 的 NotifyGC。
Flutter Canvas 实践
Flutter 包含了 Skia,可提供 Canvas 能力。之前的逻辑是通过 Dart 调用 Engine,再调到 Skia,而我们通过实践中对其部分 API 的暴露,将 Skia 的 Canvas 能力加以透出。在 JS 部分有一些 2D 和 3D 的 API,可以将这些暴露成为 Canvas API,整体而言,相比于 Web 的 Pipeline 表现非常不错,这一功能目前已经在部分业务开始灰度测试,数据表现也非常不错。
AOP 框架(AspectD)
Flutter 的 AOP 框架的核心基于 dill 变换,dill 本身是从 Dart 代码到最终代码之间的中间语言表达。其原理简要来说是当我们写了一个 hello_fultter 的时候,再写一个 AOP 包,AOP 的包会包裹 hello_fultter 包,使得在 AOP 包的产物 (dill) 里面 hello_flutter 和 AOP 的逻辑都存在,即其包括两部分内容,hello_flutter 本身代码的 dill 表达,以及 AOP 框架中写的注解的 dill 表达,将这两者都包含在 app.dill 里面,基于此我们可以通过 dill transform 方式来做变换。这里比较复杂,需要考虑 AST 抽象语法树的各种逻辑。需要将注解提取出来并基于这些注解进行操作,并最终写入到 dill 里面去,这些操作处理完成之后,就变成了 aop_aspectd.dill,替换掉之前的 app.dill 即可。
四 AliFlutter 研发模式探索
AliFlutter 研发模式
下图中最重要的就是研发模式和跨平台运行时,目标是提供一种多端多平台的能力。在平台底层是基础库、网络库的基础能力,此外还需要在垂直能力上的扩展,支持各种垂直的基础能力。基础设施之上是 Flutter 的跨平台运行时,运行时基于 Flutter Engine,提供了具有丰富表达力的图形接口、跨平台、能力拓展、性能以及稳定性等。在此之上,Flutter Framework 提供了可以复用的基础能力,比如核心布局渲染、弹性扩展能力、组件能力以及定制性等。除此之外,也有一些研发支撑上面的工作,比如编译打包、调试、灰度发布、线上监控、运维能力以及数据化等。
AliFlutter 研发模式展望
在 Flutter 的未来发展方向,阿里巴巴主要的工作将集中于以下四点:
- 跨端能力:我们考虑对于上层的各种平台提供标准基础能力并 API 化,从而更好在多端多平台进行部署。此外,还希望通过 Flutter 的容器化,使得研发和业务方能够更多地专注在自身业务上面去。
- 交互能力:我们考虑利用 Flutter 丰富的表达能力在游戏化方向进行更好的扩展,以游戏引擎的方式来开发 APP。基于泛化的交互能力以及更多的可玩性和创新性能够为业务带来更多可能。
- 研发效率:我们考虑实现工程解耦和云端一体化,目标是业务方只需关注所写的包,通过很简洁的方式集成进来并看到效果,从而提供类似于前端的开发体验。此外通过云端一体从面向端侧负责转变到面向业务整体负责。
- 交付效率:这部分主要包含两部分,一部分是动态化 UI,另外一部分是 Web On Flutter,期望通过提供更加灵活的动态性,以及前端技术栈下的动态化能力。
总结
在本文中,首先,为大家分享了 Flutter 的原理,介绍了 Flutter 美观、高效、高性能、开放的特点,以及阿里巴巴为什么选择 Flutter。其次,为大家分享了 Flutter 的业内现状,有大量投入的主流厂商,以及体系化、深度、框架和更多的探索。再次,为大家介绍了 AliFlutter 的建设与实践,包括了业务、研发模型、引擎研发等方面的实践。最后,展望了对于 AliFlutter 研发模式的考量和未来发展方向。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。