Keframe 分帧入屏: 处理flutter卡顿,优化流畅度

引言

在掘金上浏览到Nayuta开源的贝壳flutter流畅优化组件 Keframe。在Demo上试用了一番,确有奇效,下面记录一下笔记心得。

Keframe 处理思路

  • 卡顿的本质
    在一帧内,模块运行的时间太长,计算量太大

Keframe 方案:分帧入屏 ,既然单帧的绘制时间太长,那我们就将一帧分成多帧。
将屏幕上的 widget 扔进一个执行队列,将模块内的时间做拆分,多个 widget 不同时进行绘制,一个绘制完成后再进行下一个 widget 的绘制。

Keframe 使用方法
  • 添加依赖(非空安全使用: 1.0.2; 空安全版本使用: 2.0.2)
dependencies:
  keframe: version
  • 优化前的代码
// CellWidget 是一个复杂的Item widget
ListView.builder(
      itemCount: 100t,
      itemBuilder: (c, i) => CellWidget(),
    )
  • 使用Keframe 优化
ListView.builder(
      itemCount: 100t,
      itemBuilder: (c, i) => FrameSeparateWidget(
          index: i,
          placeHolder: placeHolderWidget(),
          widget: CellWidget(),
      ),
    )

FrameSeparateWidget: 分屏组件
index: id标识,非必传,使用 SizeCacheWidget的场景必传
placeHolder: 占位widget
widget: 真实需要渲染的widget

借用一下作者的图解:


假如现在页面由 A、B、C、D 四部分组成,每部分耗时 10ms,在页面时构建为 40ms。使用分帧组件 FrameSeparateWidget 嵌套每一个部分。页面构建时会在第一帧渲染简单的占位,在后续四帧内分别渲染 A、B、C、D。

另外 Keframe 还提供了一个工具类SizeCacheWidget用于缓存子节点中,分帧组件嵌套的实际 widget 的尺寸信息。对于列表,在每一个 item 中嵌套 FrameSeparateWidget,并将 ListView 嵌套在 SizeCacheWidget 内即可。

SizeCacheWidget(
    child: ListView.builder(
     ...省略
    itemBuilder: (c, i) => FrameSeparateWidget(
    ...省略
    ),
    ),
)
SizeCacheWidget 的作用:

当不确定实际 item 高度的时候,给 placeholder 设置一个近似的高度。并且在将 ListView 嵌套在 SizeCacheWidget 中。记录已渲染 widget 的大小尺寸,对于已渲染过的 widget 设置占位的尺寸。在滚动过程中,已经渲染过的 item 将不会出现跳动情况。


原理分析

  • 分帧入屏


    FrameSeparateWidget
  • initState 初始化时 resultWidget 赋值为占位Widget
  • transformWidget initState和didUpdate都会触发,监听占位绘制完成,并将替换任务扔进分帧队列中
FrameSeparateTaskQueue
  • 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进行存储。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本篇为 Flutter 技术原理基础篇章,了解了底层原理后,可以更好的展开诸如状态管理、Navigator 页面导...
    wanderingGuy阅读 806评论 0 2
  • 1. 简介 在介绍Flutter布局之前,我们得先了解Flutter中的一些布局相关的特性。 1.1 边界约束(b...
    24K纯城阅读 529评论 0 0
  • 最近技术早读会接触了一下 Flutter 优秀的开源库 Keframe, github 链接 点这里 [http...
    _烩面_阅读 2,999评论 0 4
  • 转自 Q吹个大气球Q 本文主要介绍了Flutter布局相关的内容,对相关知识点进行了梳理,并从实际例子触发,进一步...
    chilim阅读 1,972评论 0 17
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,628评论 28 53