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閱讀 773評論 0 2
  • 1. 簡介 在介紹Flutter布局之前,我們得先了解Flutter中的一些布局相關的特性。 1.1 邊界約束(b...
    24K純城閱讀 526評論 0 0
  • 最近技術早讀會接觸了一下 Flutter 優秀的開源庫 Keframe, github 鏈接 點這里 [http...
    _燴面_閱讀 2,813評論 0 4
  • 轉自 Q吹個大氣球Q 本文主要介紹了Flutter布局相關的內容,對相關知識點進行了梳理,并從實際例子觸發,進一步...
    chilim閱讀 1,962評論 0 17
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,592評論 28 53