简介: 从“麻绳版顺滑”到“丝般顺滑”
作者:闲鱼技术-云从
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 秒内,跳过执行 Choreographer 中 doFrame() 的次数 (见 《挪动App性能评测与优化》)
- SM(Smooth,晦涩度)
- 在单位工夫 1 秒内,理论执行 Choreographer 中 doFrame() 的次数。其中 SM=60-SF。(见 《挪动App性能评测与优化》)
- 帧耗时数据
应用 adb 命令失去几个要害分位的帧均匀耗时:
Total frames rendered: 2245Janky frames: 31 (1.38%)50th percentile: 5ms90th percentile: 10ms95th percentile: 14ms99th percentile: 18ms
然而以上工具和指标定义在 app 的简单场景下,尚存在问题
- 多平台问题
现 APP 技术有原生、h5、小程序、RN、weex、flutter 等。暂无一款无侵入的晦涩度检测工具能同时反对多个平台、多种机型和多个指标数据,而侵入式的检测工具无奈检测竞品 APP。 - 指标抉择和用户体验一致性
咱们冀望能有大量的几个指标数据,精确的表白用户晦涩度体感。
均匀 FPS(SM 和 SF 相似),不足以反映用户体验。如雷同 30 FPS,能够是 1s 内 30 个 33.3 ms的画面,也能够是 29 个 16.6ms 的画面再加 1 个 516.9 ms 的画面,但用户体验并不相同。
- 晦涩度数据影响因素多
滑动速度和滑动状态: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 线程执行视图操作。
具体应用代码样例如下
- 注解视图类
应用 ViewDataAnno 注解视图类,UIMethodAnno 注解 UI 操作方法。
其中注解阐明
- 生成 ViewData 类
业务代码批改
- 批改视图变量为 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 上 View
→ Tool Windows
→ Flutter 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 26111-15 15:03:43.701 27076 27271 I flutter : CommonBuyDetailPage performance: ItemBodyAction.onScrollBroadcast 193311-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 查看渲染线程性能耗费,能够发现有多个 ClipRectLayer
和 ClipRRectLayer
。
关上 Debug flag debugDisableClipLayers
和 debugDisablePhysicalShapeLayers
从新查看视图,能够发现局部 ClipRectLayer 是因为图片内容超出视图边界产生,局部 ClipRRectLayer 是因为卡片 Widget 圆角设置以及基于外接纹理的图片控件里设置了 ClipRRect 设置(即使 radius 为0也会设置)
了解原理后,咱们对闲鱼图片控件新增参数,反对图片内容圆角设置和图片内容宽高裁剪,使 native 层生成的 Bitmap 曾经满足圆角和宽高比要求。同时修复 radius 为0也会设置 ClipRRect 的问题。优化后的 Timeline 图如下:
4.1.4 其余优化倡议
flutter 性能优化相干的优良文章很多,本文不再对相似的排查和优化伎俩做赘述,这里做下简略汇总:
widget build 优化
- setState 状态刷新地位尽量搁置于视图树的低层级
- Provider 中获取 Model 的形式会影响刷新范畴。举荐应用 Selector 或 Consumer 来获取先人 Model,以维持最小刷新范畴
- 对于长列表,防止应用 ListView() 构造函数,举荐应用 ListView.builder 构造函数
- reducer 中,state 对象中的视图数据真正发生变化的时候,新建 state 对象
主 isolate 优化
- 缩小或提早 widget build 中非视图逻辑,如曝光埋点提早到滑动进行聚合触发
- 列表 Item 高度可知的状况下,举荐设置 itemExtent,缩小滑动中频繁计算列表高度
- 应用 const 润饰无需变更的 widget 或一般对象
- 应用 AnimatedBuilder 时,防止在不依赖于动画的 widget 的构造方法中构建 widget 树。动画的每次变动都会重建这个 widget 树。而应该构建子树的那一部分,并将其作为 child 传递给 AnimatedBuilder
- 防止在动画中剪裁。如果可能,请在动画开始之前事后剪切图像
Render 线程优化
- 对于频繁更新的控件(如动画),应用 RepaintBoundary 隔离它,创立独自 layer 缩小重绘区域
- 应用图片替换半透明成果
- 缩小 saveLayer(ShaderMask、ColorFilter、Text Overflow)、clipPath的应用,晋升 render 线程性能
- 防止应用 Opacity widget,尤其是在动画中防止应用。请用 AnimatedOpacity 或 FadeInImage 进行代替
- 防止应用带换行符的长文本
工具举荐
- 官网 DevTools 工具
- 利用 Debug flags 排查问题(举荐 Flutter Performance 剖析工具简介)
- 长于利用框架日志,如 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 个方向:
- 多线程计划
在 Android 原生开发中很常见。但在 dart 世界中,不同线程(isolate)的内存是隔离的,此外因为 flutter 渲染流程三棵树,咱们不好间接操作 RenderObject,多线程计划在 flutter 中较难施行(排除 IO 更新数据后显示等惯例场景) - 优化每个工作,挤压 CPU 运算量,保障一帧工夫(16.6 ms)实现工作
- 中的支流优化思路,后面的优化伎俩都是这个思路
- 疾速响应用户,让用户感觉够快,不阻塞用户的交互。即一帧工夫内还有工作没有实现,则进行执行,保障列表先执行滑动,未执行工作在后续帧工夫片上执行
参考 React Fiber 框架,基于工夫分片的思路,协调阶段将一颗工作树转为一条工作链(parent 节点 → child 节点 → sibling 节点 → parent 节点),满足了工作链可中断执行,提前提交渲染,最初实现了将一条工作链拆解到多帧工夫分片中消化。
排除方向 1、2 后,只剩下方向 3。再联合猜你喜爱卡片 Timeline 图能够发现,在卡片 Widget 创立的一帧产生工夫有余,而前面的几帧内工夫耗费都远没到 16.6 ms,能够想到方向 3 是正确的。那剩下的关键问题仅有以下 2 点:
- 是否将一个大 Widget build 工作为拆分多个小 Widget build 工作并大抵均匀的调配到多个工夫分片上?
- 一个大 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 主动且正当地分帧上屏?