頁面流暢度不再是謎!開箱即用,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 耗時)。此時點選 ⏸ 按鈕會為我們展示收集到的耗時資訊
柱狀圖頂部為我們展示收集到的資料裡:最大耗時、平均耗時、以及總耗時(單位:毫秒)
在下方,我將頁面流暢度劃為了四個級別:流暢(藍色)、良好(黃色)、輕微卡頓(粉色)、卡頓(紅色),將 FPS 折算成一幀所消耗的時間,不同級別採用不一樣的顏色,統計不同級別出現的次數。
上面的例子中,我們可以看到,工具一共收集了 99 幀,最大耗時的一幀花了119ms,平均耗時:32.9 ms,總耗時:3259.5 ms。其中認為有 40 幀流暢,25 幀良好,38 幀輕微卡頓,6 幀卡頓。
二、Why you need this 為什麼你需要這個工具?
1、為什麼我沒選擇 PerformanceOverLay 和 DoKit?
看到上面的功能可能有人有疑惑,你這功能咋和 PerformanceOverLay 這麼類似?
首先,我在使用 PerformanceOverLay 的時候遇到了一點問題:
如圖,PerformanceOverLay 上分別為我們展示了構建(UI)耗時和渲染(GPU)耗時。
我遇到的第一個問題是,因為我們在判斷流暢度的時候,往往是看一幀的總耗時。這樣拆分之後,一幀的耗時變成了上下的和,對我而言很不直觀。
其次,這裡面提供最大耗時
或者平均耗時
並不能很好的幫助我們量化頁面的流暢程度。因為這個統計過程,會直接將一幀的耗時進行平均,這就帶來一個問題。我們知道對於60重新整理率的裝置,兩幀的間隔時間最小應該是 16.7ms,而 PerformanceOverLay 的收集過程沒有對資料過濾,會出現一幀耗時小於 16.7ms,這就導致平均資料可能偏低。(下圖平均一幀耗時為:10.6ms 60HZ裝置)
其實這樣來看,DoKit是一個不錯的選擇
但DoKit同樣沒有對最小幀耗時做過濾,也會出現平均耗時偏低的情況。同時,沒有更多的資料輔助評估頁面的流暢程度。
上面我遇到的情況,不一定是問題,只是我在使用過程中覺得不太直觀,不太方便。
因此開發了這個工具,該工具具有以下特點
同時支援設定最大采集幀數
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種內容進行測試,實驗結果如下圖所示
通過該圖我們可以看出,當幀率大於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的跳轉)
///宣告NavigatorState的GlobalKey
GlobalKey<NavigatorState> globalKey = GlobalKey();
///獲取overLayState
SchedulerBinding.instance.addPostFrameCallback((t) =>
overlayState =globalKey.currentState.overlay
);
///指定MaterialApp的navigatorKey
navigatorKey: globalKey,
複製程式碼
- 在build屬性中包裹元件
builder: (ctx, child) =>
CustomWidgetInspector(
child: child,
),
複製程式碼
3、如何使用
在完成了上述步驟之後,你只需要啟動app,該工具只會在profile/debug模式下整合,在你的右下角會出現一個 ⏯ 按鈕,點選開始記錄,再次點選顯示資料。
如果想要結束採集,點選皮膚中的停止監聽即可。
如果你想採集更多的幀,可以通過kFpsInfoMaxSize
設定
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
如果你覺得這個工具還不錯,點個贊支援一下吧~
上一期文章釋出之後取得了非常好的資料
也讓我短暫的享受了下作者榜單榜一的體驗(現在已經不在了 QAQ)
感謝各位的支援!!!和大家同步一下,為了確保開源的質量,不讓大家在使用過程中添堵,目前 BKListView 還在處於測試中(上週剛發現一個 BUG  ̄□ ̄|| 不過已修復),完成後根據公司相關流程再進行開源~ 我會持續跟進,有進展會在公眾號和掘金上同步更新。
整個開發過程中明顯的感覺到了,原始碼閱讀的重要性,如果沒有前期大量的原始碼積累,整個設計過程中也不會有這樣一些奇奇怪怪的思路。所以下一個階段,我任會持續的和大家一起有方向計劃的分享原始碼,希望我們都能一起進步。