首要做一下毛遂自荐:我是张云龙(云从),先后在网易、字节、阿里任职移动端研制。在结构组件方面,参加过动态化结构,路由组件、IOC 结构、工程模板化等项目等;在功用优化方面,担任过 WebView 功用优化、App 发动优化、流通度优化、包巨细优化等;在事务方面,参加过多款 app 研制/孵化。现在在阿里巴巴闲鱼技能部,现在担任闲鱼 app 包巨细、流通度、发动等端体会内容。

Archsummit直击|构建顺滑自然的 Flutter 页面

本次共享围绕 flutter 流通度,别离叙述:1.Flutter 流通度优化应战;2.列表容器和 FlutterDx 组件优化;3.功用衡量和 devtool 扩展;4.Flutter 滑动曲线优化;5.功用优化主张。

Flutter 流通度优化应战

事务复杂度应战

Archsummit直击|构建顺滑自然的 Flutter 页面

Archsummit直击|构建顺滑自然的 Flutter 页面

Flutter 一直以高功用被咱们所认知,Flutter Gallery(左图所示)展现的列表控件,也确实十分流通。但实践事务场景(右图所示)比 Gallery 列表 demo 复杂的多:

1.相同的卡片,有更多和复杂(如圆角)的视图控件;2.列表翻滚时,有更多的视图逻辑,如翻滚操控其他控件渐显和消失;3.卡片控件,也有更多的事务逻辑,如根据后台数据操控不同的标签、活动价等,也有埋点等常见事务逻辑;4.由于闲鱼是电商 App,所以咱们需求有必定的动态才能应对频繁多变的活动。这儿咱们运用阿里自研的 Flutter DynamicX 组件完成咱们的动态才能。

结构完成的应战

Archsummit直击|构建顺滑自然的 Flutter 页面

咱们再来看列表翻滚的全体流程,这儿只重视手指放开后的自在翻滚阶段。

1.手指松开时,根据 ScrollDragController.end 核算初始速度;2.UI Thread 向 Platform Thread 请求 requestFrame,在 Platform Thread 收到 Vsync 信息,则向 UI Thread 调用 beginFrame;3.UI Thread Animate 阶段触发列表滑动一点间隔,一起向 Platform Thread 注册下一帧回调;4.UI Thread Build Widget,再经过 Flutter 三棵树 Diff 算法生成/更新 RenderObject 树;5.UI Thread RenderObject 树 Layout、Paint 生成 Scene 目标,最终传递给 Raster Thread 进行制作上屏;

上述流程,必须要 16.6 ms 内完成,才能确保不掉帧。大部分状况,不需求构建新的卡片,但当新卡片进入列表区域时,整个核算量就会变得巨大,尤其是在复杂的事务场景下,怎么确保在一帧 16.6ms 内完成悉数核算,是一个不小的应战。

Archsummit直击|构建顺滑自然的 Flutter 页面

上图是一次滑动 devtool 样例,卡顿阶段都是新卡片上屏时产生,其他阶段均很流通,由于翻滚速度在衰减,所以卡顿间隔也在变大。由于大部分时分都很流通,所以均匀 FPS 不低。但新卡片构建时的产生画面中止,给咱们的卡顿体感却很显着。

动态才能的应战 – Flutter DynamicX

Archsummit直击|构建顺滑自然的 Flutter 页面

闲鱼 App 卡片运用自研 Flutter DynamicX 来支持咱们的动态才能。基本原理:在线修正布局 DSL,生成 dx 文件并下发。端侧经过解析 dx 文件,并结合后台卡片数据,生成 DXComponentWidget,最终生成 Widget Tree。Flutter DynamicX 技能给闲鱼带来动态更新的才能,共同监控才能(如在 DXComponentWidget 监控卡片创立),良好研制体感(在线 DSL 和 Android Layout 基本共同,对 Android 开发优化),在线修正才能;

但在功用上,咱们也付出了必定的代价:DX 卡片比较增加了模板装载和数据绑定开支,Widget 要经过 WidgetNode 递归遍历动态创立,视图嵌套层级会更得更深(后续叙述)。

阐明:Flutter DynamicX 参阅阿里集团 DSL 规矩完成

用户体感的应战

Archsummit直击|构建顺滑自然的 Flutter 页面

前面已经叙述过,相同 FPS 下,Flutter 列表的卡顿体感更显着;

在 Android RecycleView 产生小卡顿(16.6*2ms)时,体感并不显着,而 Flutter 列表在产生卡顿时,不仅时间上中止,滑动 Offset 上也产生了跳变,为此小卡顿的体感也变得显着了;

假定列表内容足够简单,翻滚不会产生卡顿,咱们也发现 Flutter 列表和 Android RecycleView 也不太相同:

•运用 ClampingScrollPhysics,在列表快中止的时分,会感受到相似磁铁吸住的感觉。•运用 BouncingScrollPhysics,列表翻滚开端时,速度衰减的更快;

在 90hz 机器上,前期 Flutter 列表并不流通,原因是部分机器上,触控采样率是 120hz,屏幕改写率是 90hz,导致部分画面是 2 次触控事情,部分是 1 次触控事情,最终导致翻滚 offset 产生跳变。在 Flutter 1.22 版别时,能够运用 resamplingEnabled 对触控事情进行重采样。

列表容器和FlutterDx组件优化

Archsummit直击|构建顺滑自然的 Flutter 页面

叙述了 Flutter 流通度优化的应战,现在来共享闲鱼怎么优化流通度,并沉淀进 PowerScrollView 和 Flutter Dynamic 组件。

PowerScrollView 规划和功用优化

Archsummit直击|构建顺滑自然的 Flutter 页面

PowerScrollView 是闲鱼团队自研 Flutter 列表组件,在 Sliver 协议上有了更好的封装和弥补:数据增修正方面,弥补了部分改写;布局方面,弥补了瀑布流;事情方面,弥补了卡片上屏、离屏、翻滚事情;操控方面,弥补了翻滚到 index 的才能。

在功用方面,弥补了瀑布流布局优化、部分改写优化、卡片分帧优化和滑动曲线优化。

PowerScrollView 瀑布流布局

Archsummit直击|构建顺滑自然的 Flutter 页面

PowerScrollView 瀑布流布局供给了纵向布局、横向布局、混排布局(横向卡片和一般卡片混排)。现在闲鱼大部分列表页面均选用 PowerScrollView 的瀑布流布局,如首页同城页、搜索成果页等。

PowerScrollView 瀑布流布局优化

Archsummit直击|构建顺滑自然的 Flutter 页面

首要经过惯例的缓存优化,缓存每个卡片左上角 x 值和归于哪一列。
比较 SliverGrid 卡片是并排进入列表区域,而瀑布流布局,咱们需求界说 Page,卡片进场创立和离场毁掉需求以 Page 为单位。优化前,Page 以屏幕可视区域为单位核算卡片,一起为了确认 Page 的起点 Y 值,一次布局需求核算 Page N 和 N+1 二页,所以参加布局核算的卡片量较多,功用变低。优化后,运用悉数卡片高度均匀值的近似值核算 Page,极大削减参加布局卡片的数量,一起 Page 离场毁掉的卡片数量也变少。
Archsummit直击|构建顺滑自然的 Flutter 页面

经过列缓存和分页优化,运用闲鱼自研 benchmark 东西(后续介绍)比照瀑布流和 GridView,检查丢帧数和最差帧耗时,能发现功用体现基本共同。

PowerScrollView 部分改写优化

Archsummit直击|构建顺滑自然的 Flutter 页面

闲鱼产品希望用户浏览产品更流通,不会被 loadmore 加载打断,所以列表在翻滚进程中就需求触发 loadmore。Flutter SliverList 在 loadmore 弥补卡片数据时,会对 List 控件标脏,而标脏后 SliverList build 会毁掉悉数卡片偏从头创立,此刻功用数据能想象十分的差。PowerScrollView 供给了布局改写优化:缓存屏幕上的悉数卡片,不再从头创立,UI Thread 耗时从原来的 34ms 优化至 6ms(见左下图),右图检查 Timeline,视图构建的深度和复杂度均有显着优化。

PowerScrollView 卡片分帧优化

Archsummit直击|构建顺滑自然的 Flutter 页面

左图2个卡片是闲鱼前期搜索成果页,当时还不是瀑布流。检查卡片创立时的 Timeline 图(弥补了 Dx Widget 创立 和 PerformLayout 开支),能够发现一次卡片创立的复杂度极大,在一般中端机器上,UI Thread 耗机遇已经超出 30ms,要优化至 16.6ms 以内,用惯例的优化手法就很困难了。为此想象 2 个卡片能否拆解掉,各自运用 1 帧的时间去烘托。
Archsummit直击|构建顺滑自然的 Flutter 页面

直接看源码,基本思想是:对卡片 Widget 进行标记,在左面卡片实在创立的时分,右边卡片先 _buildPlaceholderCell 构建占位 Widget(空的 Container),并注册监听下一帧。鄙人一帧,右边卡片进行修正 needShowRealCell 为 true,并自我标脏,此后构建实在内容。

推迟构建卡片实在内容,是否会对显现内容产生影响?由于 Flutter 列表在可视区域上下还有 CacheExtends 区域,这部分区域用户不可见。为此在大部分场景下,用户并不会看到空白卡片的场景。

同样运用 Flutter BenchMark 东西进行功用测验,能看到卡片分帧前后 90分位,99分位帧耗时都有显着的降级,丢帧数也从 39 下降至 27

这儿留意,监听下一帧的时分,需求 WidgetsBinding.instance.scheduleFrame() 触发 requestFrame。由于在列表首屏显现的时分,有可能由于没有下一帧的回调,导致推迟显现队列的使命没有履行,最终使得首屏内容显现不正确。

推迟分帧优化思路和运用主张

Archsummit直击|构建顺滑自然的 Flutter 页面

比照 Flutter 和 H5 规划比较挨近:

1.dart 和 js 都是单线程模型,跨线程通讯需求走序列化和反序列化;2.Flutter Widget 和 H5 vDom 相似,都有一个 Diff 进程。

前期 FaceBook 在 React 优化时,提出了 Fiber 架构:根据 vDom tree 的父节点→子节点→兄弟节点→子节点的方法,将 vDom tree 转化为 fiber 数据结构(链式结构),从而完成 reconcile 阶段的可中断可恢复;根据 fiber 数据结构,操控部分 fiber 节点鄙人一帧继续操作。

根据 React Fiber 思路,咱们提出了自己的推迟分帧优化,不只是左右卡片粒度,更进一步,将烘托内容拆解为当前帧使命、高优推迟使命和低优推迟使命,上屏优先级依次变低。其中当前帧使命,是左右 2 个空白 Container;高优推迟使命独占一帧,其中图片部分也运用 Container 占位;在闲鱼场景,咱们把悉数的 DX Image Widget 从卡片内拆解出来,作为低优推迟使命,并设置在一帧消费不超越 10 个。

经过将 1 帧显现使命拆解到 4 帧时间,高端机上最高 UI 耗时从 18ms 优化至 8ms。

阐明1:不同事务场景下,高优使命和低优使命设置要有所不同 阐明2:在低端机(如 vivo Y67)上快速列表滑动,分帧计划会让用户看到列表变白和内容上屏的进程

Flutter-DynamicX组件优化-原理详解

Archsummit直击|构建顺滑自然的 Flutter 页面

在线修正“类 Android Layout DSL”,编译生成二进制 dx 文件。端侧经过文件下载、加载和解析,生成 WidgetNode Tree,见右图。
Archsummit直击|构建顺滑自然的 Flutter 页面

之后结合后台下发的事务数据,经过递归遍历 WidgetNode Tree 动态生成 Widget Tree,最终显现上屏。

阐明:Flutter DynamicX 参阅阿里集团 DSL 规矩完成

Flutter-DynamicX组件优化-缓存优化

Archsummit直击|构建顺滑自然的 Flutter 页面

知道了原理,就容易发现上图赤色框中的流程:二进制(模板)文件解析装载、数据绑定、Widget 动态创立都有必定的开支。为避免重复开支,咱们对 DxWidgetNode 和 DxWidget 均进行了缓存,蓝色选中代码展现了 Widget 缓存。

Flutter-DynamicX组件优化-独立 isolate 优化

Archsummit直击|构建顺滑自然的 Flutter 页面

此外,将上述逻辑放置到独立 isolate 中,最大极限的将开支下降至最低。经过线上技能灰度 AB 试验,均匀卡顿坏帧份额从 2.21% 下降至 1.79%。

Flutter-DynamicX组件优化-层级优化

Archsummit直击|构建顺滑自然的 Flutter 页面

Flutter DynamicX 供给了类 Android Layout DSL,为完成每个控件 padding、margin、corner 等特点,增加了 Decoration 层;为完成类 Android FrameLayout、LinearLayout 布局才能,增加了 DXContainerRender 层。每一层都有自己的明晰责任,代码层次明晰。但也由于增加 2 层导致 Widget Tree 层级变深,3棵树的 Diff 逻辑变得复杂,功用变低。为此,咱们将 Decoration 层和 DXContainerRender 层进行了合并,检查中心 Timeline 图,能够发现优化后的燃焰图层级和复杂度都变低。经过线上技能灰度 AB 试验,均匀卡顿坏帧份额从 2.11% 下降至 1.93%。

功用衡量和devtool扩展

叙述了优化手法,这儿叙述咱们的流通度功用怎么做衡量,以及东西的构建/扩展。

Archsummit直击|构建顺滑自然的 Flutter 页面

线下场景-flutter benchmark

Archsummit直击|构建顺滑自然的 Flutter 页面

Archsummit直击|构建顺滑自然的 Flutter 页面

检测 Flutter 每帧耗时,需求核算 UI Thread 和 Raster Thread 上的核算耗时。所以 Flutter 优化前后比较,运用 SchedulerBinding.instance.addTimingsCallback 获取每一帧的 UI Thread 和 Raster Thread 的耗时数据。
此外,流通度功用数值受操作手势、翻滚速度影响,所以根据人工操作的测量成果会存在误差。这儿运用 WidgetController 操控列表控件 fling。

东西供给设置翻滚速度、翻滚次数、翻滚之间的间隔时间等。翻滚测验完成后,显现 UI 和 Raster Thread 丢帧数,50分位、90分位、99分位的帧耗时等数据,从多种维度给出了功用数据。

线下场景-根据录屏的流通度检测

Archsummit直击|构建顺滑自然的 Flutter 页面

flutter benchmark 在 flutter 页面给出了多维度的测量数据,但有时分咱们需求横向比较竞品 App,所以咱们需求有东西横向比较不同技能栈的页面流通度。闲鱼在 Android 端自研了根据录屏数据的流通度检测。将手机界面想象成多个画面,经过向系统录屏服务 MediaProjection 注册获取 VirtualDisplay,间隔 16.6 ms读取其中的画面数据(字节数组),这儿运用字节数组的 hash 值代表当前画面,当前后 2 次读取的 hash 值不变,则以为产生了卡顿。

为了确保流通度检测东西 app本身不产生卡顿,这儿读取的是压缩画面数据,低端机上压缩份额要更高

Archsummit直击|构建顺滑自然的 Flutter 页面

经过东西无侵入的检测,能够检测到一次翻滚测验,均匀 FPS 值(图中 57),帧散布均方差(7.28),1s 时间产生的大卡顿次数均匀值(0.306),大卡顿累计时间(27.919)。中心数组展现帧散布状况:371 代表正常帧数量,6 代表 16.62ms 的小卡顿数量,1 代表 16.63ms 的卡顿数量。

这儿大卡顿的界说是:大于 16.6*2 ms 的卡顿

线下场景-根据devtool的功用检测

Archsummit直击|构建顺滑自然的 Flutter 页面

此外,闲鱼线下场景也扩展了 devtool。在一次 Timeline 图扩展了每个阶段的耗时,大于 16.6ms 赤色高亮显现,便捷了开发运用。

线上场景-Flutter高可用检测FPS完成原理

Archsummit直击|构建顺滑自然的 Flutter 页面

Archsummit直击|构建顺滑自然的 Flutter 页面

在线上场景,闲鱼自研了 Flutter 高可用。基本原理是根据2个事情:

•ui.window.onBeginFrame 事情

•engine 告诉 Vysnc 信号到来,告诉 UI Thread 开端预备下一帧画面构建•触发 SchedulerBinding.handleBeginFrame 回调

•ui.window.onDrawFrame 事情

•engine 告诉 UI Thread 开端制作下一帧画面•触发 SchedulerBinding.handleDrawFrame 回调

这儿咱们在 handleBeginFrame 处理之前,记载一帧开端事情,在 handleDrawFrame 之后记载一帧的结束。这儿每一帧都需求核算列表控件 offset 值,详细代码完成见右图。在整个累计超越 1s 时,履行一次核算,运用 offset 过滤掉没有产生翻滚的场景,运用每一帧的时间核算 fps 值。

线上场景-FlutterBlockCanary线上卡顿仓库检测

Archsummit直击|构建顺滑自然的 Flutter 页面

运用 Flutter 高可用核算得到线上 FPS 数值后,怎么定位卡顿问题,需求搜集仓库信息。闲鱼运用自研的 FlutterBlockCanary 搜集卡顿仓库。基本原理是,在 C 层轮询发送信号,比如 5ms 一次,每次信号接收触发 dart UI Thread 仓库收集,对得到的一系列仓库进行聚合,连续多次相同仓库就以为是产生了卡顿,这时这个仓库便是咱们想要的卡顿仓库。
下图是 FlutterBlockCanary 收集的仓库信息,中心 FrameFpsRecorder.getScrollOffset 便是产生卡顿的调用。

线上场景-FlutterBlockCanary检测过度烘托

Archsummit直击|构建顺滑自然的 Flutter 页面

此外,FlutterBlockCanary 也集成了过度烘托检测的才能。经过复写 WidgetsFlutterBinding 的 buildOwner 方法替换 BuildOwner 目标,从而重写 scheduleBuildFor 方法,完成拦截脏 element。根据脏 element 节点,提取出脏节点的深度、直接子节点的数量、悉数子节点的数量。
根据悉数子节点数量,在闲鱼详情页,咱们定位到“快速发问视图”在翻滚进程中,频繁被标脏和悉数子节点数量过大。检查代码,定位该视图层级过高,经过将视图下沉到叶子节点,一次标脏 build 节点数量从 255 优化至 43。

Flutter 滑动曲线优化

前面叙述了卡顿优化手法和衡量东西和标准,首要仍是围绕着 FPS。但从用户体感出发,咱们发现 Flutter 也有许多可优化点。

Archsummit直击|构建顺滑自然的 Flutter 页面

Flutter 列表滑动曲线和原生曲线

Archsummit直击|构建顺滑自然的 Flutter 页面

别离比照 offset/time 的翻滚曲线,能够发现 Flutter BouncingScrollSimulation 和iOS 翻滚曲线挨近,ClampingScrollSimulation 和 RecyclerView 挨近。检查 Flutter 源码注释,也确实是如此。

由于 BouncingScrollSimulation 具有回弹才能,所以许多下拉改写和加载更多功用,都是根据 BouncingScrollSimulation 封装完成,这也就造成 Flutter 页面滑动时,体感和原生 Android 页面不共同的原因。

Flutter 列表在快速滑动下的体现和优化

Archsummit直击|构建顺滑自然的 Flutter 页面

虽然 ClampingScrollSimulation 滑动曲线和 Android RecyclerView 挨近,但在快速滑动场景下,能够发现 Flutter 列表翻滚快中止的时分会像磁铁吸住一般,快速滑动一下中止。究其原因,能够看到滑动曲线快中止的瞬间,速度并不是下降,而会加快,最终抵达终点,快速中止。根据源码公式,制作曲线,能够发现,Flutter ClampingScrollSimulation 是经过公式拟合方法,去迫临 Android RecyclerView 曲线(BSpline)。在快速滑动的状况下,公式曲线的要点并不是 1 对应的值,而是右图虚线方位,速度会变快。

能够理解 Flutter 的公式拟合成果并不理想,为此近期也有 PR 提出运用 dart 完成了 RecyclerView 曲线。

Flutter 列表在卡顿状况下的体现和优化

Archsummit直击|构建顺滑自然的 Flutter 页面

第一章提过相同 FPS 状况下,如 FPS 55,原生列表感受流通,而 Flutter 列表的卡顿体感更显着。这儿一个原因是原生列表一般有多线程操作,呈现大卡顿的概率更低;另一个原因是,相同小卡顿的体感,Flutter 有显着的卡顿感,而原生列表简直感受不出来。那这是为什么呢?

咱们在构建卡片的时分,故意制作小卡顿,在前后比照 Flutter 列表和 RecyclerView,能够发现 RecyclerView offset 并不会产生跳变,而 Flutter 曲线有许多毛刺,由于 Flutter 翻滚是根据 d/t 曲线核算,当产生卡顿的时分,△t 产生翻倍,offset 也产生跳变。也正是由于时间中止和 Offset 跳变,让用户显着感受到 Flutter 列表在小卡顿的不流通感。

Archsummit直击|构建顺滑自然的 Flutter 页面

经过修正 y=d(t) 公式,在卡顿状况下,将△t-16.6ms,确保小卡顿状况下,offset 不产生跳变。而在大卡顿状况下,就没有必要将 △t 重置为 16.6ms 了,由于在中止时长上,已经显着让用户给感受到卡顿了,offset 不产生跳变只会让列表翻滚间隔变短。

功用优化主张

Archsummit直击|构建顺滑自然的 Flutter 页面

Archsummit直击|构建顺滑自然的 Flutter 页面

最终共享一些功用优化的主张。

1.在优化时,咱们更应该重视用户体感,而不是只看功用数值。右上图可见,即便 FPS 值相同,但 offset 产生跳变,体感就会有显着的不同;右下2个游戏录屏,左面均匀 40 FPS,右边均匀 30 FPS,但体感上却是右边的更顺畅。2.不仅要重视 UI Thread 的功用,也要重视 Raster Thread 的开支,如视图圆角、save layer 等特性/操作,也可能导致卡顿3.在东西方面,主张在不同场景下运用不同的东西。需求留意的是,东西检测的问题,是安稳复现问题仍是数据颤动产生的偶现问题。此外,也要考虑东西本身的功用开支,东西本身的 CPU 占用和主线程占用都需求尽可能下降。4.在优化思路方面,咱们要扩宽方向,Flutter 大部分优化思路都是优化核算使命;而多线程方向也并不是不能够,参阅前面 Flutter DynamicX 的独立 isolate 优化;此外,一帧时间难以消化的使命,是否有可能拆解到多个帧时间,尽量让每帧时间不产生卡顿,优先响应用户。5.最终,引荐重视 Flutter 社区。Flutter 社区继续有各种优化合入,定期晋级 Flutter 或维度自己的版别,cherry-pick 优化提交,都是不错的挑选。

功用分析东西运用主张

Archsummit直击|构建顺滑自然的 Flutter 页面

Flutter 东西方面,首推的便是官方的 DevTools 东西,里面的 Timeline 和 CPU 燃焰图能很好的协助咱们发现问题;此外,Flutter 也供给了丰富的 Debug Flags 协助咱们定位问题,熟悉每一个 debug 开关作用,相信对咱们日常研制也会有不小的帮助;除了官方东西,功用日志也是很好的辅助信息,如右下角所示,闲鱼 fish-redux 组件输出了翻滚中的使命开支时长,能便利的看出那一时间产生了卡顿。

功用分析东西本身开支

Archsummit直击|构建顺滑自然的 Flutter 页面

功用检测东西不可避免会有必定的开支,但必定要操控在可接受范围内,特别是线上运用。前面共享过 FlutterBlockCanary 检测东西的一个事例,发现了 FrameFpsRecorder.getScrollOffset 有耗时状况,而这处逻辑正好是 Flutter 高可用核算翻滚 Offset。见右图的优化前源码,每一帧都需求递归遍历搜集 RenderViewPortBase,是一个不小的开支。最终,咱们经过缓存优化的方法,避免了翻滚进程中的重复核算。

卡顿优化主张

Archsummit直击|构建顺滑自然的 Flutter 页面

参阅官方文档和优秀的功用文章,在 UI 和 GPU 侧都沉淀了许多惯例优化手法,如改写最小 Widget,运用 itemExtent,引荐运用 Selector 和 Consumer 等,避免了不必要的 Diff 核算、布局核算等;如削减 saveLayer、运用图片替换半透明效果等减轻了 Raster 线程的开支。

由于篇幅原因,这儿只列了一部分,更多的常见优化主张见官方文档。

运用最新 flutter engine

Archsummit直击|构建顺滑自然的 Flutter 页面

前面提过,Flutter 社区还在活跃,Framework 和 Engine 层继续的有优化 PR 合入,这些优化手法大部分能够让事务层无感知,而且从底层视角更好的优化功用。

这儿举一个典型的优化计划:现有 Flutter 计划:在每次 VSync 信号到来时,触发 Build 操作,在 Build 结束时,开端注册下一个 VSync 回调。在没有产生卡顿的状况下,见图 Normal。但在产生卡顿的状况下,见图 Actual results,这儿2 Build耗时刚刚超越了 16.6ms,由所以注册监听下一个 VSync 回调时触发下一次 Build,为此中心空余了大量的时间。显着,咱们所希望的是,2 Build结束是,立即履行3 Build,假定3 Build履行的足够快,这个时分用户看到的画面仍是流通的。

如果团队允许,主张定期晋级 Flutter 版别;或者维护自己的 Flutter 独立分支也是不错的挑选,从社区 Cherry-Pick 优化提交,既能确保事务安稳也能享用社区奉献。总之,引荐咱们重视社区。

总结

综上,共享了 Flutter 流通度优化的应战、监控东西、优化手法和主张。功用优化要以人为中心,从实践体感入手拟定监控指标和优化点;流通度优化并不是一蹴即至,以上共享也不是悉数,还有许多优化手法能够重视:怎么更好的复用 Element,怎么避免 Platform Thread 繁忙导致 Vsync 信号缺失等都是能够重视的点,只要继续的技能热情和匠心精力才能把 App 功用优化到极致;技能团队也要和开源社区、其他团队/公司树立连接,他山之石,能够攻玉。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。