keframe 实现分帧渲染上屏,优化流畅度

前言

卡顿的产生

为什么一帧的耗时会超过16.7ms?为了搞清楚这个问题我们需要知道,Flutter为了绘制一帧会做些什么?

绘制过程分析:首先 dart 通过 Window_scheduleFrame 方法调用 engine,之后 engine 向 Choreographer 注册一个 vsync 回调。等到下一个 vsync 信号来到时,通过 nativeOnVsync 将整个渲染任务 post 到 UI task 的队列中,回调到 Flutter之后经历以下流程:

image.png

关键步骤有三:

Build:通过widget 配置生成 Element 与 RenderObject 树

Layout:遍历 RenderObject 树,测量每一个页面元素的大小与决定位置

Paint:根据 RenderObject 树中的节点生成 Layer 树,合成语义化后提交给 engine 给 GPU 进行渲染

对于复杂列表卡顿问题主要由于 build 阶段耗时过长。


image.png

Flutter 的列表一般都采用 Lazy Build 的方式生成列表单元,当列表单元接近可见区域的时候,列表根据视窗高度与缓存区大小,动态构建和布局多个 item。

不管是对于列表还是非列表而言,卡顿大多由于构建耗时引起。从本质来看,就是一个模块的执行时间过长。

Keframe作为flutter的一个流畅度解决方案,已受到业界很多关注。

Keframe 原理是基于分帧渲染,针对单一计算量过大以及复杂列表的滚动,提升效果非常明显。

在 Flutter 中,Widget/Element/Render 三棵树的概念非常重要,而分帧渲染的原理,其实就是在 Tree 上分层,将一些复杂的节点及其子节点,用一些空 Widget 占位,而原本应该被渲染的节点,放在下一帧去渲染,从而避免出现太复杂的 UI,使得一帧的单帧的渲染时间过长,导致卡顿。

这里给出个流畅度指标信息:
1.流畅:一帧耗时低于 18ms
2.良好:一帧耗时在 18ms-33ms 之间
3.轻微卡顿:一帧耗时在 33ms-67ms 之间
4.卡顿:一帧耗时大于 66.7ms

如何使用

在 pubspec.yaml 中添加 keframe 依赖

 keframe: 2.0.2

版本说明:
非空安全使用:1.0.1;
空安全版本使用:2.0.2;

方案设计与分析:

如图所示:


image.png

根据图示,原理清晰明了,问题是flutter如何实现这一过程。

源码分析

分帧上屏
FrameSeparateWidget
initState 初始化时 resultWidget 赋值为占位Widget
transformWidget initState和didUpdate都会触发,监听占位绘制完成,并将替换任务扔进分帧队列中

分帧队列
分割任务帧队列
await SchedulerBinding.instance!.endOfFrame : 如果当前正在绘制,等待当前帧结束。如果当前空闲,强制进行一帧的绘制,并等待结束。
await taskItemQueue.first.run() : 该方法为callback回调,真实内容就是替换占位widget

SizeCacheWidget
//自定义冒泡通知
class LayoutInfoNotification extends Notification {
  final Size size;
  final int? index;
  LayoutInfoNotification(this.index, this.size);
}
子组建
父组建

子组件重写performLayout方法,将尺寸大小通过冒泡通知给父组件,父组件根据id进行存储。

分帧的成本
当然分帧方案也非十全十美,在我看来主要有两点成本:
1、额外的构建开销:整个构建过程的构建消耗由「n * widget消耗 」变成了「n *( widget + 占位)消耗 + 系统调度 n 帧消耗」。可以看出,额外的开销主要由占位的复杂度决定。如果占位只是简单的 Container,。这种额外开销对于当下的移动设备而言,成本几乎可以不计。

2、视觉上的变化:组件会将 item 分帧渲染,页面在视觉上出现占位变成实际 widget 的过程。但其实由于列表存在缓存区域(建议将缓存区调大),在高端机或正常滑动情况下用户并无感知。而在中低端设备上快速滑动能感觉到切换的过程,但比严重顿挫要好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容