关于程序员:他把闲鱼APP长列表流畅度翻了倍良心教程

49次阅读

共计 10508 个字符,预计需要花费 27 分钟才能阅读完成。

简介: 从“麻绳版顺滑”到“丝般顺滑”

作者:闲鱼技术 - 云从

1 整体思路

闲鱼在业务的疾速迭代过程中,app 的长列表滑动晦涩度逐渐好转,对用户浏览内容体验产生挫伤。闲鱼作为国内 flutter 利用的先驱,APP 以 flutter 和原生 Native 的混合工程存在。这里别离就 Android 原生、flutter 页面和大家分享咱们的优化思路。

本文分为三个局部:

  • 晦涩度指标和检测工具构建
  • 原生 Android 长列表优化
  • flutter 长列表优化

晦涩度优化整体思路图如下:

2 晦涩度指标和检测工具构建

2.1 现状和难点

检测工具现状:以 Android 为例,现有晦涩度工具可分为:

  • 侵入式

    • 集成 sdk,通过注册帧回调计算晦涩度。Android 见 Choreographer 类
    • profile 模式
  • 无侵入式

    • 执行系统命令,如 adb shell dumpsys gfxinfo ${packageName}
    • 腾讯 GT APP,底层执行 service call SurfaceFlinger 1013,高版本 Android 已不反对

晦涩度指标现状有:

  • FPS (Frames Per Second)
  • SF(SkippedFrame,跳帧)
  1. 在单位工夫 1 秒内,跳过执行 Choreographer 中 doFrame() 的次数(见《挪动 App 性能评测与优化》)
  • SM(Smooth,晦涩度)
  1. 在单位工夫 1 秒内,理论执行 Choreographer 中 doFrame() 的次数。其中 SM=60-SF。(见《挪动 App 性能评测与优化》)
  • 帧耗时数据
    应用 adb 命令失去几个要害分位的帧均匀耗时:
Total frames rendered: 2245
Janky frames: 31 (1.38%)
50th percentile: 5ms
90th percentile: 10ms
95th percentile: 14ms
99th percentile: 18ms

然而以上工具和指标定义在 app 的简单场景下,尚存在问题

  1. 多平台问题
    现 APP 技术有原生、h5、小程序、RN、weex、flutter 等。暂无一款无侵入的晦涩度检测工具能同时反对多个平台、多种机型和多个指标数据,而侵入式的检测工具无奈检测竞品 APP。
  2. 指标抉择和用户体验一致性
    咱们冀望能有大量的几个指标数据,精确的表白用户晦涩度体感。

均匀 FPS(SM 和 SF 相似),不足以反映用户体验。如雷同 30 FPS,能够是 1s 内 30 个 33.3 ms 的画面,也能够是 29 个 16.6ms 的画面再加 1 个 516.9 ms 的画面,但用户体验并不相同。

  1. 晦涩度数据影响因素多
    滑动速度和滑动状态:idle(进行)、drag(手指拖拽)、fling(自在滑动)都是影响晦涩度数据的重要因素。

2.2 晦涩度指标制订

维基百科 动画定义:一种通过定时拍摄一系列多个静止的固态图像(帧)以肯定频率间断变动、静止(播放)的速度(如每秒 16 张)而导致肉眼的视觉残象产生的错觉——而误以为图画或物体(画面)流动的作品及其影片技术。

列表滑动同理,是 APP 以肯定频率(60hz 下 16.6ms)和不同 offset 计算出一系列静止画面,让肉眼看到滑动动画。

当咱们说列表滑动不晦涩,是因为频率过低无奈让肉眼产生视觉残留,或在工夫(画面停留时长)和空间(画面内容)产生跳变,让用户感知到变动的不天然。以此咱们能够定义指标如下:

  • 工夫角度

    • 定义均匀 FPS:定义一次检测的均匀帧率。反馈画面均匀停留时长。
    • 定义 1s 大卡顿次数:均匀 1s 内呈现占用 3 帧及以上的画面次数。反馈画面停留时长跳变
  • 空间角度

    • offset 跳变值:在画面不掉帧的状况,若其中一个画面呈现跳变,甚至花屏或者绿屏会让用户体验到不晦涩。在 APP 滑动过程中,画面内容由 offset 决定,而 offset 跳变,和卡登时长、差值器实现均有关联,现有差值器实现根本基于 D/T 曲线(间隔 / 工夫),为此均匀 FPS 和 1s 大卡顿次数很大水平上体现了画面跳变,同时思考到无侵入式检测 offset 的难度问题,暂不思考 offset 跳变值。

综上,咱们定义晦涩度指标为均匀 FPS 值和 1s 大卡顿次数。

2.3 晦涩度检测工具实现

咱们从 APP 录屏画面动手,计算晦涩度指标值。当咱们失去 APP 滑动过程中的录屏数据,可通过每 16.6ms 检测录屏画面是否发生变化,当间断画面未发生变化,则示意产生了卡顿。无变动的间断画面数则示意了卡顿的时长。

为失去指标 APP 录屏数据,检测工具 APP 向零碎注册录屏服务,而后在检测工具 APP 的帧回调中不停读取录屏画面,并和上次检测画面 hash 值进行比对。

  • 检测工具 APP 和指标 APP 过程隔离,为此指标 APP 产生卡顿并不影响检测工具 APP 的帧回调
  • 为保障每次录屏画面读取和 hash 值计算在 16.6ms 内实现,需依据高低端机型调整画面宽高压缩比。

为排除滑动操作对晦涩度数值的烦扰,咱们应用脚本操作检测工具 APP 和指标 APP 的滑动。自动化脚本原理为应用 adb 命令操作手机

点击:adb shell input tap $x $y
滑动:adb shell input swipe $x1 $y1 $x2 $y2 $duration

2.4 检测工具演示

晦涩度检测工具 APP 以悬浮框的形式显示,上面为指标检测 APP:

晦涩度检测工具界面

2.5 小结和瞻望

在晦涩度指标方面,咱们定义了均匀 FPS 和 1s 大卡顿次数作为指标,更好的反馈了用户体验。
在晦涩度检测工具方面,咱们实现了无侵入检测工具,反对以下个性:

  • 无侵入
  • 反对检测第三方 app
  • 反对多平台:native,flutter,h5,小程序
  • 多维度数据:均匀 FPS,均匀 1s 大卡帧次数,帧散布直方图,帧散布均方差
  • 主动操作,防止人为操作差别

此外,晦涩度检测工具还有一些不足之处

  • 列表中有视频卡片

    • 进行滑动时,若列表中有视频播放,因为画面始终在变动,检测工具无奈判断是滑动进行;同时,因为视频 fps 值为 30 左右,会导致晦涩度数据偏低
    • 如何防止:检测过程中,需保障列表滑动不进行
  • 低端机(y67)实在 fps 计算存在偏差

    • 为保障低端机上(如 vivo y67)上计算大图像 hash 值在 16ms 以内,录屏画面压缩较大(宽度压缩 100,高度压缩 10),为此在大量空白或者大色块的场景下,无奈检测到画面的轻微变动,fps 计算存在偏低。
    • 如何防止:防止低端机上检测大量空白或大色块的场景

3 原生 Android 长列表优化

Android 原成长列表优化曾经十分成熟了,在工具方面有 traceview、blockcanary、DDMS、Android Profile 等。常见优化伎俩也很多:布局层级优化,适度渲染优化,频繁 measure、layout 优化,UI 线程耗时办法优化、冗余资源资源加载优化等,这里不再赘述。

除此之外闲鱼应用以下 2 点优化首页

3.1 异步构建视图缓存池

通过工具检测或耗时打印,发现列表初始滑动和 loadmore 时触发 item 视图构建耗时重大(RecyclerView.onCreateViewHolder)

查看首页显示和初始滑动流程,能够发现流程中其余 UI 操作过程和期待用户操作过程均有优化空间。

利用 AsyncLayoutInflater 原理异步构建视图缓存池,优化首页列表流程如下:

其中视图缓存池构建实现的机会在不同机型下不同,可能在列表首屏多卡片构建之前,或构建中,或在用户滑动操作之前实现,或一开始构建就抛出谬误进行构建

留神:不能间接应用 AsyncLayoutInflater,AsyncLayoutInflater 在异步构建失败后有一个降级到 UI 线程构建的逻辑,为防止降级逻辑产生导致缓存池在 UI 线程构建,导致页面更加卡顿,须要移除这个降级逻辑:呈现异步 inflater 失败,进行缓存池构建。

3.2 ViewDataUnbinder 疾速抽离 UI 操作

在卡片数据绑定阶段(RecyclerView.onBindViewHolder),在低端机上耗时较为重大,起因是在卡片数据绑定办法中,而 UI 和非 UI 操作糅合在一起,因为 UI 逻辑必须在 UI 线程执行,最终导致全副逻辑只能在 UI 线程执行。

能想到定义视图数据层,将 UI 和非 UI 操作分来到,然而理论编码发现业务代码改变量大且容易出错,AB 测试逻辑难以实现。那有没有更好的计划,用最大量代码抽离 UI 操作呢?

外围思路:编译期依据视图类主动生成 ViewData 类,并替换视图类实例。ViewData 类和视图类领有雷同的要害办法签名,办法执行时记录视图操作,对立切换到 UI 线程执行视图操作。

具体应用代码样例如下

  1. 注解视图类
    应用 ViewDataAnno 注解视图类,UIMethodAnno 注解 UI 操作方法。

 其中注解阐明

  1. 生成 ViewData 类

  1. 业务代码批改

    • 批改视图变量为 ViewData 类型
    • 原视图数据绑定逻辑搁置后盾线程

3.3 优化后果

.gif”)

闲鱼首页,在复原内容上屏速度(晦涩度升高)后晋升晦涩度

4 Flutter 简单长列表优化

flutter 始终以高性能被大家所认知,参考 Flutter 是如何做到性能直逼 native 的?,这也是闲鱼当初抉择 flutter 的一个重要起因。而在闲鱼的理论 flutter 页面,如商品详情页和搜寻后果页,长列表滑动晦涩度体验却不尽人意。

4.1 工具应用和常见优化

做性能优化前,须要了解 flutter 的渲染原理,如 Widget、Element、RenderObject 三棵树构造、Widget 到屏幕显示过程等,可参考 超详解析 Flutter 渲染引擎,简单业务如何保障 Flutter 的高性能高晦涩度?。

针对性能问题,首推官网性能剖析工具并联合应用 profile 模式查看性能问题,参考 Flutter Performance 剖析工具简介。

Profile 模式只能在真机上运行,不能在模拟器上运行:根本和 Release 模式统一,除了启用了服务扩大和 tracing,以及一些为了最低限度反对 tracing 运行的货色(比方能够连贯 observatory 到过程)。命令 flutter run –profile 就是以这种模式运行的,通过 sky/tools/gn –android –runtime-mode=profile 或者 sky/tools/gn –ios –runtime-mode=profile 来 build。因为模拟器不能代表实在场景,所以不能在模拟器上运行
引自:Flutter 性能调优、简单业务保障 Flutter 的高性能高晦涩

4.1.1 查看 widget rebuild 状况

Android Studio 上 ViewTool WindowsFlutter Performance 关上检测 Widget rebuild 状况,能够发现 FDButtonBar 被频繁重建,然而查看视图内容并没有发生变化。查看代码定位到 reducer.dart 中会依据滑动事件更新 state 中的 scrollPercent,进而产生重建。而在详情页中,scrollPercent 在 Widget 构建中并未参加应用。

闲鱼页面中应用了 fish-redux,在 reducer.dart 的办法中返回不同的 state 对象则示意须要重建 widget

// reducer.dart
// 滑动事件监听
  static BottomBarState onScroll(BottomBarState state, Action action) {
    ...
    return state.clone()..scrollPercent = scrollPercent;
    ...
  }

4.1.2 应用 fish-redux 性能日志

fish-redux 是闲鱼研发一套在 flutter 上的 redux 框架,闲鱼 APP 中有广泛应用。fish-redux 中自带性能日志,源码查看 performance.dart,若须要打印 profile 或 release 模式下的性能日志,可自行批改源码。

闲鱼详情页滑动时,查看 adb 日志,能够发现大量的滑动播送告诉,且存在耗时 1ms 以上事件处理。

11-15 15:03:43.684 27076 27271 I flutter : CommonBuyDetailPage performance: ItemBodyAction.onScrollBroadcast 261
11-15 15:03:43.701 27076 27271 I flutter : CommonBuyDetailPage performance: ItemBodyAction.onScrollBroadcast 1933
11-15 15:03:43.716 27076 27271 I flutter : CommonBuyDetailPage performance: ItemBodyAction.onScrollBroadcast 371

profile 模式下工夫日志


因为详情页中存在视图间联动,如标题栏的显示暗藏突变,问卖家 的显示隐没均须要依据滑动事件做判断。联合业务逻辑,能够发现,除了 问卖家 外,其余视图在滑动超出 600 之后,收到滑动事件后不会产生视图内容变动;而 问卖家 在滑动超出更大的一个值后会永远隐没不显示,在一开始未超出这个值时,仅须要判断滑动方向即可。基于以上业务背景,在滑动超出 600 后,若 问卖家 是不再显示状态,则不发送滑动事件;否则仅在开始滑动的 30 间隔内发送事件。

此外,能够利用 fish-redux 的个性:若 reducer.dart 中返回新的 state 对象则示意 widget 重建,查看全副的 reducer.dart 文件内办法实现,排查可能产生的有效 widget 重建。

4.1.3 优化 ClipPath 和 ClipRPath

应用 Timeline 查看渲染线程性能耗费,能够发现有多个 ClipRectLayerClipRRectLayer


关上 Debug flag debugDisableClipLayersdebugDisablePhysicalShapeLayers 从新查看视图,能够发现局部 ClipRectLayer 是因为图片内容超出视图边界产生,局部 ClipRRectLayer 是因为卡片 Widget 圆角设置以及基于外接纹理的图片控件里设置了 ClipRRect 设置(即使 radius 为 0 也会设置)

了解原理后,咱们对闲鱼图片控件新增参数,反对图片内容圆角设置和图片内容宽高裁剪,使 native 层生成的 Bitmap 曾经满足圆角和宽高比要求。同时修复 radius 为 0 也会设置 ClipRRect 的问题。优化后的 Timeline 图如下:

4.1.4 其余优化倡议

flutter 性能优化相干的优良文章很多,本文不再对相似的排查和优化伎俩做赘述,这里做下简略汇总:

  • widget build 优化

    1. setState 状态刷新地位尽量搁置于视图树的低层级
    2. Provider 中获取 Model 的形式会影响刷新范畴。举荐应用 Selector 或 Consumer 来获取先人 Model,以维持最小刷新范畴
    3. 对于长列表,防止应用 ListView() 构造函数,举荐应用 ListView.builder 构造函数
    4. reducer 中,state 对象中的视图数据真正发生变化的时候,新建 state 对象
  • 主 isolate 优化

    1. 缩小或提早 widget build 中非视图逻辑,如曝光埋点提早到滑动进行聚合触发
    2. 列表 Item 高度可知的状况下,举荐设置 itemExtent,缩小滑动中频繁计算列表高度
    3. 应用 const 润饰无需变更的 widget 或一般对象
    4. 应用 AnimatedBuilder 时,防止在不依赖于动画的 widget 的构造方法中构建 widget 树。动画的每次变动都会重建这个 widget 树。而应该构建子树的那一部分,并将其作为 child 传递给 AnimatedBuilder
    5. 防止在动画中剪裁。如果可能,请在动画开始之前事后剪切图像
  • Render 线程优化

    1. 对于频繁更新的控件(如动画),应用 RepaintBoundary 隔离它,创立独自 layer 缩小重绘区域
    2. 应用图片替换半透明成果
    3. 缩小 saveLayer(ShaderMask、ColorFilter、Text Overflow)、clipPath 的应用,晋升 render 线程性能
    4. 防止应用 Opacity widget,尤其是在动画中防止应用。请用 AnimatedOpacity 或 FadeInImage 进行代替
    5. 防止应用带换行符的长文本
  • 工具举荐

    1. 官网 DevTools 工具
    2. 利用 Debug flags 排查问题(举荐 Flutter Performance 剖析工具简介)
    3. 长于利用框架日志,如 fish-redux 性能日志

4.2 列表 element 复用优化

flutter 列表控件划分为可视区域和 Cache 区域,往下滑动时 element 从底部被创立进入底部 Cache 区域后,再进入可视区域,再进去顶部 Cache 区域,最初被销毁。往上滑动逻辑相似。在不应用 keepAlive 的状况下,来回滑动,已经创立过的 element 须要从新创立。而在咱们的业务中,列表 item Widget 构造是靠近的,此时如果能依据类型复用 element,就能肯定水平的晋升性能。

列表控件源码见 sliver_list.dart 中 RenderSliverList.performLayout()
element 缓存在 _childElements 数组中,以 index 为索引。源码见 sliver.dart
若 item Widget 构造差别很大,即使复用了 element,Element.updateChild 办法外部最终还是执行了 inflateWidget 办法,对于性能晋升就没什么价值了

咱们构建 index${widget.key}List<element> 的映射关系:在 widget 创立处建设 index${widget.key} 映射,在 element 应该被销毁移除的逻辑处,将 element 缓存至 ${widget.key} 映射的 List<element> 处(留神 renderObject 对象须要从父节点移除)。列表滑动过程中,优先依据映射关系找到缓存中的 element 并应用( 留神 更新 element.renderObject.parentData 中的 index 值)

4.3 简单 Widget 分帧上屏

以上全副优化伎俩尝试后,在闲鱼的详情页和搜寻页上还是远没有达到预期。起因是猜你喜爱卡片和搜寻页卡片自身就足够简单,另外因为咱们引入 DX 技术让 Widget 进一步变得微小,最终导致的后果是:即使高端机,也无奈在一帧工夫内实现渲染。
然而抛开技术视角,从业务视角看,卡片展示内容和 DX 的动静能力都是必须的。那如何在满足业务诉求的状况下,实现超大 Widget 的高性能呢?

业务侧仅需 Text,但在 DX 技术中应用的是 DXTextWidget

猜你喜爱卡片在 红米 K30Pro(CPU 骁龙 865)的 Timeline 图

搜寻后果卡片 Timeline 图,补充了 performLayout、updateChild、Widget build

在已知常见优化伎俩无奈满足的状况下,咱们回归 GUI 零碎性能优化的终点去思考问题。晦涩度优化思路,大体能够分为 3 个方向:

  1. 多线程计划
    在 Android 原生开发中很常见。但在 dart 世界中,不同线程(isolate)的内存是隔离的,此外因为 flutter 渲染流程三棵树,咱们不好间接操作 RenderObject,多线程计划在 flutter 中较难施行(排除 IO 更新数据后显示等惯例场景)
  2. 优化每个工作,挤压 CPU 运算量,保障一帧工夫(16.6 ms)实现工作
  3. 中的支流优化思路,后面的优化伎俩都是这个思路
  4. 疾速响应用户,让用户感觉够快,不阻塞用户的交互。即一帧工夫内还有工作没有实现,则进行执行,保障列表先执行滑动,未执行工作在后续帧工夫片上执行
    参考 React Fiber 框架,基于工夫分片的思路,协调阶段将一颗工作树转为一条工作链(parent 节点 → child 节点 → sibling 节点 → parent 节点),满足了工作链可中断执行,提前提交渲染,最初实现了将一条工作链拆解到多帧工夫分片中消化。

排除方向 1、2 后,只剩下方向 3。再联合猜你喜爱卡片 Timeline 图能够发现,在卡片 Widget 创立的一帧产生工夫有余,而前面的几帧内工夫耗费都远没到 16.6 ms,能够想到方向 3 是正确的。那剩下的关键问题仅有以下 2 点:

  1. 是否将一个大 Widget build 工作为拆分多个小 Widget build 工作并大抵均匀的调配到多个工夫分片上?
  2. 一个大 widget 分工夫片上屏是否会影响体验?

Timeline 上工作耗时图

Flutter widget 拆分和分帧上屏

基于工夫分片的大方向,咱们把一个大 widget 拆分为一个空白框架和 2 个卡片 widget,再将卡片 widget 拆分为一个卡片框架和多个 FXImage Widget,Widget 框架中不立马显示的局部应用占位 Widget 长期代替。
由此构建一个高优大工作队列和一个低优小工作队列,高优大工作队列中的工作高优执行且独占一帧工夫,低优小工作队列低优执行且一帧工夫最多能执行 12 个工作。再利用 flutter 逐渐标脏,将 build 工作提早到后续工夫分片上。

以上最终将一个超大 widget 构建从 1 帧工夫扩散到 4 帧工夫内消化,优化了卡顿。

优化后猜你喜爱卡片 Timeline 图(红米 K30Pro,CPU 骁龙 865)

在体验方面,后面讲列表控件构造时已知有一个不可见的 Cache 区域,所以分帧上屏大部分是在这个不可见区域实现的,为此在高端机或失常滑动状况下用户并无感知。而在低端机上疾速滑动能显著看到卡片空白状况,但整体相比重大顿挫体感要好。

4.4 优化数据

基于下面的优化伎俩,闲鱼详情页和搜寻页晦涩度 FPS 晋升了 3 个点,低端机大卡顿次数升高一半,中高端机型上晦涩度晋升到 57 或以上,大卡顿次数靠近 0。

详情页 线上高可用 fps 数据如下:

线上低端机 fps 曲线。绿色为优化版本
曲线散布越靠右,晦涩度越好

线上高端机 fps 曲线。绿色为优化版本

搜寻页 线上高可用 fps 数据如下:

线上低端机 fps 曲线。绿色为优化版本

线上高端机 fps 曲线。绿色为优化版本

4.5 滑动差值器优化

实现下面优化后,线下自建晦涩度检测工具数据和线上 fps 数据曲线都有很大的晋升,且数据指标靠近原生 APP 晦涩度。在中高端机型上,闲鱼详情页 FPS 曾经被咱们优化到了 57 及以上了,1s 大卡顿次数靠近 0。在原生 APP 晦涩度 FPS 数值达到 57 及以上时,滑动过程中基本上不会感触到卡顿,然而,flutter 页面的理论滑动操作中,还是能感触到卡顿。

回顾自建晦涩度检测工具原理:基于每帧画面比对、无侵入,雷同的自动化脚本,所以置信咱们线下测试的数据(均匀 FPS 和 1s 大卡顿次数)是精确的。性能数据靠近,而体感有差别,且性能数据精确可信,所以能够确认晦涩度指标(均匀 FPS 和 1s 大卡顿次数)还不能齐全反馈体感。

再回顾 2.2 晦涩度指标制订,能够发现咱们并没有对空间维度的 offset 跳变(画面内容跳变)做检测。基于此,咱们能够比照 Android 原生 RecyclerView 和 Flutter SliverList 在卡顿状况下 offset 变动状况

Android 原生 RecyclerView 和 Flutter SliverList fling 阶段 offset/time 曲线图

由上能够失去,同样在 FPS 值达到 57,Android RecyclerView 在用户体感上比 flutter 列表控件更好的起因:在小卡登时,offset 偏移值并没有产生翻倍跳变。

查看 flutter 滑动算法,能够发现是基于一条 D/T 曲线计算滑动间隔,所以产生卡登时,输出 timeOffset 值产生翻倍,最终计算出来的 offset 值产生近乎翻倍。

flutter ClampingScrollSimulation D/T 曲线

为打消在产生小卡登时,offset 跳变的状况,咱们自定义了 physics 和 simulation,在 time 产生产生小跳变时,批改滑动间隔算法,采纳 V/T 曲线算法,distance 通过累加的形式计算,优化了 time offset 产生翻倍而导致曲线跳变的状况

distance = velocity(time) * 16.6ms + distance

留神:须要适配零碎频率大于 60 hz 的机型(如 90hz,120hz),在一帧工夫内有可能计算屡次 distance

以 V/T 曲线为根底,咱们提供了以下滑动差值器:

  • SmoothClampingScrollPhysics
    无回弹差值器,进展后偏移值不跳变。完结滑动的成果同 ClampingScrollSimulation

  • SmoothBouncingScrollPhysics
    回弹差值器,进展后偏移值不跳变

5 总结和瞻望

通过上述优化,在原生 Android 方面,闲鱼首页晦涩度和内容上屏失去显著晋升;在 Flutter 方面,闲鱼详情页和搜寻页晦涩度 FPS 晋升了 3 个点,低端机大卡顿次数升高一半,中高端机型上晦涩度晋升到 57 或以上,大卡顿次数靠近 0,雷同小卡顿在体验上失去了晋升。

晦涩度优化是每一个 GUI 零碎都始终在致力的事件,有很多优良的工具介绍、官网和非官方的优化文章。这次优化过程中,咱们也借鉴了很多他人的文章,发现和优化了一些问题,但本文尽量不去反复形容,举荐读者浏览相干优化文章或官网文档。
在以上优化伎俩尚无奈实现最终目标时,咱们也做了一些不一样的优化,冀望能抛砖引玉,对读者有所帮忙和启发:

  • 基于用户体验为导向构建了晦涩度指标:均匀 FPS,1s 大卡顿次数
  • 针对指标,自建了晦涩度检测工具,反对无侵入、跨平台、自动化
  • [Android] 显示 ViewDataUnbinder 组件在简单业务逻辑中疾速抽离 UI 操作
  • [Flutter] 批改 Flutter engine 源码,反对列表 element 复用
  • [Flutter] 实现大 Widget 分帧上屏组件
  • [Flutter] 差值器算法优化

后续咱们会持续思考以下内容:

  • 如何将晦涩度检测工具外部产品化,反对非研发共事应用?
  • 如何应用已有的教训、工具、组件疾速优化其余业务页面?
  • 如何在研发阶段及时发现和避免有效 rebuild 等问题?
  • 如何在 CI 平台及时发现页面晦涩度好转状况?
  • 如何以业务无侵入的形式实现业务大 Widget 主动且正当地分帧上屏?

正文完
 0