UC Flutter技术实践分享

简介: UC于19年开始探索Flutter技术,并在同年年底进行规模化落地。规模化落地Flutter核心要解决的三类问题分别是工程构建体系的搭建,性能优化和动态性支持。本次分享将由阿里巴巴UC事业部无线开发专家刘森森为大家详细介绍UC在规模化落地Flutter过程中解决的问题,及其思考过程。

摘要:UC于19年开始探索Flutter技术,并在同年年底进行规模化落地。规模化落地Flutter核心要解决的三类问题分别是工程构建体系的搭建,性能优化和动态性支持。本次分享将由阿里巴巴UC事业部无线开发专家刘森森为大家详细介绍UC在规模化落地Flutter过程中解决的问题,及其思考过程。

演讲嘉宾简介:阿里巴巴UC事业部无线开发专家——刘森森(花名:森尼)。14年加入UC,长期在UC信息流团队负责信息流业务的技术工作,近一年投入到创新产品的研发中,负责Flutter技术在创新产品的应用与实践。
以下内容根据演讲视频http://mudu.tv/watch/5624777以及PPT整理而成。

本次分享主要围绕以下五个方面:

            一、Flutter在UC落地的情况  
            二、工程体系构建  
            三、性能优化  
            四、动态性探索  
            五、总结  

一、Flutter在UC落地的情况

业务落地情况

Flutter具备高性能、高效率两个特性。UC作为创新事业群的一部分,以创新为重要使命,希望Flutter可以直接加速UC的创新。目前UC国内有50%的研发同学已经使用Flutter。从前需要两端开发的需求现在一端人力就可以支撑,并且前端同学可以加入做Native需求的行列,研发效率得到大幅度提升。

目前UC有两类业务。一类是成熟业务,例如UC和夸克,其新功能会优先考虑使用Flutter。一类是创新业务,例如小萌圈和古桃,基本都使用Flutter开发UI。

屏幕快照 2020-06-22 下午3.09.15.png

夸克&UC具体业务形态

夸克&UC的业务形态是将Flutter嵌入Native框架,是混合栈开发模式。业务以feed流为主,内容以音视频、图片、GIF为主。

屏幕快照 2020-06-22 下午3.11.47.png

创新产品

90%页面使用Flutter开发。未来发展的方向即UI将尽可能使用Flutter进行开发。

屏幕快照 2020-06-22 下午3.12.55.png

总览

UC落地Flutter有多种场景,目前的阶段是将Flutter规模化落地到创新业务中,加速UC的创新发展。

当前UC的Flutter落地面临着以下三类问题。

工程构建体系:如何提高Flutter落地效率?
性能优化:UC业务痛点在哪里?
动态性探索:如何结合业务实现动态性?

二、工程构建体系

核心目标——高效率

可快速集成到现有APP。
可快速构建全新的Flutter应用。
研发可快速上手。

工程架构

将Flutter业务落地到UC中有两种方案。

集成到现有APP:Add Flutter to Existing APPs。目前UC使用的是Flutter Boot解决方案。Flutter Boot提供了两个核心优势。一,产物集成和源码集成可配置。UC中有部分同学是没有用到Flutter的,在开发中应该避免由于Flutter打包带来的效率损耗,所以希望面向该部分同学配置产物集成方式。面向flutter开发同学希望配置源码集成方式。以实现效率最大化。

二,Flutter Boot提供Native和Flutter开发两种视角。Native开发视角指在Native工程中执行Native的构建脚本、命令。官方方案只能使用Native开发,无法使用一些flutter tool的高效命令,会造成研发效率的下降。另外,前端同学更希望使用Flutter原生命令,而不希望理解安卓和iOS两种构建体系的差别,因此Flutter Boot对前端同学友好。

集成到Flutter APP:全新APP。推荐使用Flutter官方解决方案,更高效、简单。

工程架构:Flutter业务以Package依赖的工程结构组织。UC是多团队、多业务的开发模式,期望业务之间解耦。目前Flutter不支持产物分离,都打包在一起,因此前期希望在工程方面尽可能做到解耦。公共组件会放到UC pub中,pub管理比git管理更加高效直观。目前UC pub中沉淀了许多业务组件和技术组件。UC pub上游可进行修改。技术组件打磨成熟后可以回归Ali pub或pub dev。

屏幕快照 2020-06-22 下午3.14.08.png

业务架构

业务架构核心思路是抽象几个核心模块,构建架构模板,使业务开发同学有一致认知。

最下方使用Flutter Boost解决方案,Flutter Boost是开源比较久的混合栈的解决方案。UC是Flutter Boost的重度用户,同时积极反哺社区,例如支持hero动画等。即使UC使用了Flutter Boost,UC希望Flutter页面之间的相互跳转是使用原生方式,支持hero动画可以使动画做的更漂亮。

每个Package使用Flutter Redux,主要是因为Flutter Redux能够解决复杂场景的状态管理。另外许多前端同学拥有Redux开发经验,可以带领客户端同学学习。

屏幕快照 2020-06-22 下午3.15.38.png

UC通过上述业务架构约束,使研发认知一致聚焦,降低研发上手的成本。

分层架构

UC在业务层下面构建了容器。容器最底层包含端基础设施,有阿里巴巴集团和UC沉淀多年的移动组件。这些组件将被包装为Flutter基础组件提供给业务。Flutter基础组件、Flutter容器、端基础设施可以打造一致的API层提供给业务层去做接入。

好处是开发新APP时,一致的API层均可以复用。
根据分层架构可以做进一步思考,一致的API层能否更方便地进行业务迁移?例如UC正经部是在UC里做的,是能否将其方便地孵化为一个创新APP。UC正经部的功能是使用Package依赖,能否方便地将其提取出来放到其他APP中。这是一个比较理想化的实现,但其方向是可以研究的。

屏幕快照 2020-06-22 下午3.16.36.png

UC通过以上三种架构模板解决Flutter落地到业务的效率问题。后续会随着社区和业务的发展,进一步优化架构体系。

三、性能优化

核心目标——解决业务痛点

做业务高可用建设。
引擎启动速度优化。
视频外接纹理方案优化。
图片组件优化。

业务高可用

UC主要做了两件事。

指标体系:一是构建了一套指标体系,与Web和Native的指标模型一致。有以下指标项。

页面打开性能:页面首帧绘制、内容首帧、首屏可交互。

页面流畅度:平均帧率,卡顿帧率。

页面稳定性:白屏检测,异常收集,网络请求异常。
UC的高可用组件在闲鱼高可用基础上进行了升级,增加了一些指标,并支持原生Navigator。

itrace:二是将收集到的数据上传到了实时监控平台itrace上。itrace是UC使用了多年的实时监控平台服务。目前itrace对内、对外可接入。

对外: https://yueying.effirst.com
对内: https://yuque.antfin-inc.com/wpk/help/ppxlrg

itrace主要有以下优势。一,分钟级别的实时性。二,提供多维度的分析方式。三,支持聚合,快速定位top问题。四,可配置预警规则。

Flutter实时大盘:如下图所示(样例),以实时图表形式展现数据。

屏幕快照 2020-06-22 下午3.18.36.png

高可用——页面性能:页面打开流程如下。首先监听路由跳转,在路由起始时打一个起始点,然后监听每一帧的回调。第一帧回调视为首帧,打一个点,继续检测,直到图片、文字、视频等Render Object出现,打一个内容首帧。内容首帧贴近用户视角。继续检测直到组件覆盖度大于60%,打一个首屏可交互。

该逻辑中还添加了白屏检测,可从dart层检查是否有文字、视频、图片。

页面性能在itrace上的展示形态如下。将内容首帧、可交互时间全部展示出来。下方是其实时曲线。可以选择分钟级别、小时级别、天级别。每一个业务下可能有多个页面,可以具体查看每一个页面性能。

页面帧率使用handleBeginFrame和handleDrawFrame计算每一帧的耗时。通过算法可以计算出平均帧率与卡顿帧率。

屏幕快照 2020-06-22 下午3.19.30.png

目前页面性能仅支持UI Thread的监控。handleFrame方案是实时的,可在发生卡顿时还原一些现场。

高可用——维度分析:可以根据网络类型、运营商、平台、客户端、页面版本、地区等设置维度来查看。例如将WiFi设为筛选,就可以展示出WiFi下的性能。

屏幕快照 2020-06-22 下午3.20.17.png

高可用——异常收集:此处指Dart异常收集,不包括引擎的异常收集,引擎异常崩溃走Native高可用。Dart异常重可导致白屏,轻可导致局部白屏。

使用Dart提供的runZoned进行异常收集。使用HttpOverrides做网络接口的异常采集。

异常展现在itrace上,可以按照一定的次数进行聚合,根据优先级逐个解决。另外,异常收集可配置预警规则。

屏幕快照 2020-06-22 下午3.20.39.png

引擎启动优化

问题:通过高可用监控发现页面打开的最大问题是耗时,根本原因是引擎初始化时间长。发现如下两类问题。

一,Flutter初始化时函数耗时长。例如iOS,在主线程执行创建GL Context占用了30%的时间。在子线程创建RootIsolate占用40%时间。页面渲染之前的Font Init模块耗时也较长。测试不同机型耗时100ms~200ms。
二,Flutter的主线程等待子线程执行完毕后才释放,浪费CPU。

一般优化策略:一是裁剪,裁剪对引擎的侵入性较大。二是异步化,最大程度利用CPU。若异步化做得详细,入侵性也较大,因此最合理方案是针对一两个较为耗时的问题进行优化。三是将一些耗时流程延后或提前。例如在Flutter创建引擎之前进行预热。只要不是首屏就用到Flutter的场景,预热是有效的优化方式。

UC优化方案:一,在子线程预创建GL Context,引擎初始化时将复用GL Context。二,在子线程预热RootIsolate。预热之后为了不占用内存将其关闭。三,异步化。四,优化Font Init。Font Init耗时的核心原因是做了多次dlopen,可通过添加变量控制dlopen做一次即可,这个改动后续会进行更加优雅的调优,目标是回到社区。

屏幕快照 2020-06-22 下午3.21.13.png

效果:预热的内存占用仅1.4M,相比预热整个引擎需要16M有很大优势,适合混合式开发,例如UC和手淘。预热的耗时性能提升了62%,异步方案在部分机型上有约100ms的优化。Font Init优化后在安卓部分机型耗时优化50ms~90ms。

视频外接纹理

UC在视频、图片组件使用的是外接纹理方案。

外接纹理原理:通过三个步骤完成外接纹理流程。第一,Flutter通知Native获取Texture id。第二,Native同步创建并注册Texture组件给Flutter。第三, Flutter创建textureWidget通过Texture id找到Texture组件,向skia绘制。

目前iOS和安卓的外接纹理流程存在差异。安卓使用到Surface Texture,iOS使用到Flutter Texture,需要Native回写CVPixelBuffer,Flutter内部会将CVPixelBuffer绑定到Texture,当CVPixelBuffer数据发生变化,Texture会向skia进行绘制。

屏幕快照 2020-06-22 下午3.22.00.png

问题:大部分解码出的视频格式是YUV,但Flutter内部CVPixelBuffer需要BGRA格式,需进行格式转换。如何使视频格式转换不影响性能?

优化:优先考虑在iOS端不修改引擎,通过高速纹理在GPU上把YUV转换为BGRA格式。Flutter内部CVPixelBuffer绑定Texture时使用到Binding API,相反,通过Binding API也可以将Texture绑定到CVPixelBuffer上。那么向Texture绘制YUV数据时设置BGRA的转换,这样两个Texture就通过CVPixelBuffer实现共享。该格式转换不耗时,并且不会使视频出现卡顿等问题。
屏幕快照 2020-06-22 下午3.22.19.png

问题:Flutter在外接纹理时使用默认的NEAREST算法,会将纹理附近的几个颜色进行加权平均使用,导致弧形斜线等锯齿明显。

优化:已经给官方提PR:https://github.com/flutter/flutter/issues/53080

屏幕快照 2020-06-22 下午3.22.57.png

图片组件优化-外接纹理方案

问题:Flutter和Native内存无法共享。
原生方式多图滑块的场景内存回收不及时,低端机会崩溃。

侧面反映出Flutter目前图片场景做的并不够优秀。

收益:图片组件场景可以享受Native组件库成熟的优化手段,例如LRU回收,多级缓存,线程池等。以及更多的图片格式支持,如iOS的HECI格式。

效果:内存占用较Flutter原生实现减少30%左右。内存回收表现更加及时。

屏幕快照 2020-06-22 下午3.23.15.png

四、动态性探索

业务需要:UC等以feed流业务为主的,社区类的产品,产品框架比较固定,内容的动态性最为关键,即需要提供给用户好看、热点的内容。在端侧内容入口的展现形式要与内容相匹配,例如运营位置、卡片样式,这部分是有动态性诉求的。而内容打开后的动态性更希望以Web方式解决。

业务诉求:需要轻量级的动态卡片解决方案。
解决方案:Flutter box项目,UC希望技术方案更加面向Flutter社区,选取Dart作为DSL描述。Dart有三点优势。

第一,Dart对UI的描述是结构化的。例如下方左侧代码,是Dart写法,通过组装式API编写对UI的描述。该模式的好处一方面是在AST转化为需要的协议时非常贴近、自然,令一方面对于模板开发者而言是自然的写法,无需做太多约束。
第二,Dart可一体式开发,从模板编写、预览到解析执行。
第三,支持Dart语法的表达式。例如下图右侧表达式,定义了一个create函数,可在build时调用。create函数声明List的对象,通过一次for循环创建Widget将其返回给build的container。实现了动态创建Widget树的方案。

屏幕快照 2020-06-22 下午3.25.00.png

效果:将Flutter box方案落地到夸克书城,一方面提升了运营能力,一方面提升了页面加载、滑动速度,给业务带来的正向反馈。

根据测试所得性能数据,转换耗时100ms,滑动帧率50fps。转换过程指文件首先在端侧解析为中间树,为其绑定数据,再将中间树转换为Dart需要的Widget树。业务数据表现为书城点击率提升2%。

屏幕快照 2020-06-22 下午3.25.16.png

五、总结

发展阶段

现阶段UC Flutter处于规模化落地阶段。

工程构建体系

搭建了标准的工程架构。为创新业务提供了可复用的运行时容器。抽象业务核心模块,使研发具备一致认知。

性能优化

构建了性能监控体系,针对核心场景的视频、图片性能和体感进行了优化。并且性能优化方案对Flutter原生引擎修改尽可能少。

动态性探索

从业务需要出发,落地了轻量级动态卡片,满足了运营能力。

未来

UC将更加深入地挖掘Flutter,包括对引擎的优化,充分体现出Flutter在效率、性能方面的优势,为业务赋能。

屏幕快照 2020-06-22 下午3.26.13.png
关注「淘系技术」微信公众号,一个有温度有内容的技术社区~
image.png

相关文章
|
1月前
|
设计模式 前端开发 测试技术
Flutter 项目架构技术指南
探讨Flutter项目代码组织架构的关键方面和建议。了解设计原则SOLID、Clean Architecture,以及架构模式MVC、MVP、MVVM,如何有机结合使用,打造优秀的应用架构。
Flutter 项目架构技术指南
|
3月前
|
安全 Go 数据安全/隐私保护
Flutter开发笔记:Flutter路由技术
Flutter开发笔记:Flutter路由技术
343 0
|
1月前
|
开发框架 Dart 前端开发
构建响应式Web界面:Flutter的跨界前端技术
【2月更文挑战第23天】随着移动互联网的飞速发展,响应式Web设计成为现代前端开发的重要趋势。在众多框架中,Google推出的Flutter以其高效的渲染性能、跨平台能力及丰富的组件生态,为前端开发者带来了新的选择。本文将深入探讨如何利用Flutter进行高效、美观的响应式界面构建,同时剖析其与传统前端技术的差异和优势。
|
3月前
|
移动开发 前端开发 JavaScript
探究移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动端混合开发技术在移动应用开发领域日益流行,为开发者提供了更高效的跨平台开发方案。本文将比较三种主流混合开发技术:React Native、Weex和Flutter,从性能、生态系统和开发体验等方面进行评估,以帮助开发者在选择适合自己项目的技术时做出明智的决策。
|
3月前
|
移动开发 前端开发 weex
React Native、Weex、Flutter 混合开发技术的比较与选择
移动应用已经成为人们日常生活中不可或缺的一部分,而混合开发技术也随之崛起并逐渐成为主流。本文将比较 React Native、Weex 和 Flutter 三种混合开发技术,并探讨它们各自的优缺点,以及如何根据项目需求做出选择。
52 1
|
3月前
|
移动开发 前端开发 weex
移动端混合开发技术:React Native、Weex、Flutter 之争
在移动应用开发领域,React Native、Weex 和 Flutter 是备受关注的混合开发技术。本文将对它们进行全面比较与评估,以帮助开发者做出明智的选择。我们将从开发生态、性能、跨平台能力和易用性等方面进行比较,为读者提供全面的参考和指导。
|
3月前
|
移动开发 Dart 前端开发
移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动应用的开发已经成为现代社会中的重要一环。本文将比较并评估三种主流的移动端混合开发技术:React Native、Weex和Flutter。通过对它们的特点、优势和劣势的分析,帮助开发者在选择适合自己项目的技术方案时做出明智的决策。
|
3月前
|
移动开发 开发框架 前端开发
移动端混合开发技术探析:React Native、Weex、Flutter的比较与选择
随着移动应用开发的高速发展,混合开发技术成为了一种备受关注的选择。本文将对移动端混合开发技术中的React Native、Weex和Flutter进行比较与探讨,分析它们在性能、开发体验、生态系统和跨平台支持等方面的差异,以及如何根据项目需求进行选择。
62 1
|
4月前
|
Dart
Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(中)
完全基于Flutter绘图技术绘制一个精美的Dash图标(中)
47 0
|
4月前
|
Dart
Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(上)
完全基于Flutter绘图技术绘制Dart语言吉祥物(Dash)-上
35 0