頁面流暢度不再是謎!除錯神器開箱即用,Flutter FPS檢測工具

Nayuta發表於2021-04-06

頁面流暢度不再是謎!開箱即用,Flutter FPS檢測工具

學習最忌盲目,無計劃,零碎的知識點無法串成系統。學到哪,忘到哪,面試想不起來。這裡我整理了Flutter面試中最常問以及Flutter framework中最核心的知識點,歡迎關注,共同進步。![Flutter framework]

歡迎搜尋公眾號:進擊的Flutter或者runflutter 裡面整理收集了最詳細的 Flutter 進階與優化指南。關注我,獲取我的最新文章~

我的github: github.com/Nayuta403

導語:

對於任何一款應用而言,頁面的流暢度一定是影響使用者體驗最重要的幾個指標之一。作為開發者,優化頁面流暢度也是自己技術實力的體現。但在決定進行優化之前,還有兩個更重要的問題擺在我們面前:1、如何發現卡頓的頁面?2、如何衡量我的優化效果?

為了解決這兩個問題,本期給大家帶來一個很有意思的小工具:fps_monitor


一、What's this 這是個什麼工具?

首先一句話告訴你:這是一個能在 profile/debug 模式下,直觀幫助我們評估頁面流暢度的工具!! 直白來說就是:這是一個可以在(重新整理率60)裝置上直接檢視最近(預設 100)幀的表現情況的小工具,直接上圖:

當我們點選右下角的 ⏯ 後,按鈕變為⏸ 狀態,工具開始為我們收集每一幀的總耗時(包含 CPU 和 GPU 耗時)。此時點選 ⏸ 按鈕會為我們展示收集到的耗時資訊

image.png

柱狀圖頂部為我們展示收集到的資料裡:最大耗時平均耗時、以及總耗時(單位:毫秒)

在下方,我將頁面流暢度劃為了四個級別:流暢(藍色)良好(黃色)輕微卡頓(粉色)卡頓(紅色),將 FPS 折算成一幀所消耗的時間,不同級別採用不一樣的顏色,統計不同級別出現的次數。

上面的例子中,我們可以看到,工具一共收集了 99 幀,最大耗時的一幀花了119ms,平均耗時:32.9 ms,總耗時:3259.5 ms。其中認為有 40 幀流暢,25 幀良好,38 幀輕微卡頓,6 幀卡頓。


二、Why you need this 為什麼你需要這個工具?

1、為什麼我沒選擇 PerformanceOverLay 和 DoKit?

看到上面的功能可能有人有疑惑,你這功能咋和 PerformanceOverLay 這麼類似?

首先,我在使用 PerformanceOverLay 的時候遇到了一點問題:

image.png

如圖,PerformanceOverLay 上分別為我們展示了構建(UI)耗時和渲染(GPU)耗時。

我遇到的第一個問題是,因為我們在判斷流暢度的時候,往往是看一幀的總耗時。這樣拆分之後,一幀的耗時變成了上下的和,對我而言很不直觀。

其次,這裡面提供最大耗時或者平均耗時並不能很好的幫助我們量化頁面的流暢程度。因為這個統計過程,會直接將一幀的耗時進行平均,這就帶來一個問題。我們知道對於60重新整理率的裝置,兩幀的間隔時間最小應該是 16.7ms,而 PerformanceOverLay 的收集過程沒有對資料過濾,會出現一幀耗時小於 16.7ms,這就導致平均資料可能偏低。(下圖平均一幀耗時為:10.6ms 60HZ裝置) image.png

其實這樣來看,DoKit是一個不錯的選擇

image.png

但DoKit同樣沒有對最小幀耗時做過濾,也會出現平均耗時偏低的情況。同時,沒有更多的資料輔助評估頁面的流暢程度。

上面我遇到的情況,不一定是問題,只是我在使用過程中覺得不太直觀,不太方便。

因此開發了這個工具,該工具具有以下特點

image.png

同時支援設定最大采集幀數

2、我是如何理解頁面流暢度

我在上一期ListView流暢度翻倍!!Flutter卡頓分析和通用優化方案有解釋過

對於大部分人而言,當每秒的畫面達到60,也就是俗稱60FPS的時候,整個過程就是流暢的。

一秒 60 幀,也就意味著平均兩幀之間的間隔為 16.7ms。那麼耗時大於 16.7ms 就會覺得卡頓麼?

答案當然是 NO。騰訊在 Martrix 中也提到

我們平時看到的大部分電影或視訊 FPS 其實不高,一般只有 25FPS ~ 30FPS,而實際上我們也沒有覺得卡頓。 在人眼結構上看,當一組動作在 1 秒內有 12 次變化(即 12FPS),我們會認為這組動作是連貫的

其實流暢度本身就是一個很主觀的東西,就好比有人覺得打王者榮耀不開高幀率好像也還算流暢,有人覺得不開高幀率那不就是個GIF圖麼。

有沒有客觀一點的指標,我在網上查詢了很久之後找到了一篇08年發表在ICIP上的論文Modeling the impact of frame rate on perceptual quality of video 他們使用了6種內容進行測試,實驗結果如下圖所示

image.png

通過該圖我們可以看出,當幀率大於15幀的時候,人眼的主觀感受差別不大,基本上都處於較高的水平。而幀率小於15幀以後,人眼的主觀感受會急劇下降。換句話說,人眼會立刻感受到畫面的不連貫性。

因此,在工具中我將低於16.7ms的資料統一成16.7ms,所以這個檢測工具只在重新整理率為60的裝置有意義。並且將流暢度劃分為了以下等級:

  • 流暢:FPS大於55,即一幀耗時低於 18ms
  • 良好:FPS在30-55之間,即一幀耗時在 18ms-33ms 之間
  • 輕微卡頓:FPS在15-30之間,即一幀耗時在 33ms-67ms 之間
  • 卡頓:FPS低於15,即一幀耗時大於 66.7ms

並統計出現的次數,你可以根據這幾項資料,對比優化前後的資料,得出效能的提升情況;當然也可以制定一個理想的流暢度。例如:流暢的幀數佔統計幀數的90%,或者卡頓的幀數不超過5次。


三、How to use it 如何使用?

1、專案依賴

dependencies: fps_monitor: ^1.12.13-1

2、接入工程

有兩處接入點

  • 指定overLayState ,因為需要彈出一個Fps的統計頁面,所以當前指定overLayState。

(PS:大家一般使用Navigator.of(context)去跳轉一個頁面,通過GlobalKey可以實現無context的跳轉)

image.png

///宣告NavigatorState的GlobalKey
GlobalKey<NavigatorState> globalKey = GlobalKey();
///獲取overLayState
  SchedulerBinding.instance.addPostFrameCallback((t) =>
    overlayState =globalKey.currentState.overlay
    );
///指定MaterialApp的navigatorKey  
navigatorKey: globalKey,

複製程式碼
  • 在build屬性中包裹元件

image.png

builder: (ctx, child) =>
          CustomWidgetInspector(
            child: child,
          ),
複製程式碼

3、如何使用

在完成了上述步驟之後,你只需要啟動app,該工具只會在profile/debug模式下整合,在你的右下角會出現一個 ⏯ 按鈕,點選開始記錄,再次點選顯示資料。

Screenrecording_20210405_171133.gif

如果想要結束採集,點選皮膚中的停止監聽即可。

如果你想採集更多的幀,可以通過kFpsInfoMaxSize設定

Screenrecording_20210405_171154.gif

4、Warning:

目前這個專案是基於 Flutter 1.12.13 分支進行開發,如果你在接入專案中遇到了了相容性問題,歡迎評論區留言或者公眾號私信我。當然更加歡迎各位直接PR~


四、how do it 來點原理?

可能你會對這個工具的檢測原理感興趣,那我們們再來嘮兩句原理。

繪製資料的獲取

 WidgetsBinding.instance.addTimingsCallback(monitor);
複製程式碼

Flutter 會在每幀完成繪製後,會將耗時進行回撥。耗時體現在三個變數上:1、構建時間;2、繪製時間;3、總時間。當你點選 ⏯ 按鈕的時候,工具便開始採集耗時資訊。

其實對於 Flutter 相關的渲染排程,推薦大家看看 SchedulerBinding ,裡面寫得再詳細不過。

顯示Fps介面

顯示 Fps 的頁面比較簡單,直接通過 OverlayState 插入即可。如果你不太熟悉 Overlay 可以把它理解成浮窗。其中的表格繪製通過使用 DoKit 的自定義畫筆實現,當然也可替換成各種開源的圖表庫。


最後 感謝各位吳彥祖和彭于晏的點贊,Start,和Follow

如果你覺得這個工具還不錯,點個贊支援一下吧~

上一期文章釋出之後取得了非常好的資料 image.png

也讓我短暫的享受了下作者榜單榜一的體驗(現在已經不在了 QAQ)

image.png

感謝各位的支援!!!和大家同步一下,為了確保開源的質量,不讓大家在使用過程中添堵,目前 BKListView 還在處於測試中(上週剛發現一個 BUG  ̄□ ̄|| 不過已修復),完成後根據公司相關流程再進行開源~ 我會持續跟進,有進展會在公眾號和掘金上同步更新。

整個開發過程中明顯的感覺到了,原始碼閱讀的重要性,如果沒有前期大量的原始碼積累,整個設計過程中也不會有這樣一些奇奇怪怪的思路。所以下一個階段,我任會持續的和大家一起有方向計劃的分享原始碼,希望我們都能一起進步

相關文章