學習最忌盲目,無計劃,零碎的知識點沒法串成系統。學到哪,忘到哪,面試想不起來。這裏我整理了Flutter面試中最常問以及Flutter framework中最核心的知識點,歡迎關注,共同進步。![Flutter framework]
git
歡迎搜索公衆號:進擊的Flutter或者runflutter 裏面整理收集了最詳細的 Flutter 進階與優化指南。關注我,獲取個人最新文章~github
個人github: github.com/Nayuta403面試
對於任何一款應用而言,頁面的流暢度必定是影響用戶體驗最重要的幾個指標之一。做爲開發者,優化頁面流暢度也是本身技術實力的體現。但在決定進行優化以前,還有兩個更重要的問題擺在咱們面前:一、如何發現卡頓的頁面?、二、如何衡量個人優化效果?markdown
爲了解決這兩個問題,本期給你們帶來一個頗有意思的小工具:fps_monitorapp
首先一句話告訴你:這是一個能在 profile/debug 模式下,直觀幫助咱們評估頁面流暢度的工具!! 直白來講就是:這是一個能夠在(刷新率60)設備上直接查看最近(默認 100)幀的表現狀況的小工具,直接上圖:ide
當咱們點擊右下角的 ⏯ 後,按鈕變爲⏸ 狀態,工具開始爲咱們收集每一幀的總耗時(包含 CPU 和 GPU 耗時)。此時點擊 ⏸ 按鈕會爲咱們展現收集到的耗時信息svn
柱狀圖頂部爲咱們展現收集到的數據裏:最大耗時、平均耗時、以及總耗時(單位:毫秒)工具
在下方,我將頁面流暢度劃爲了四個級別:流暢(藍色)、良好(黃色)、輕微卡頓(粉色)、卡頓(紅色),將 FPS 折算成一幀所消耗的時間,不一樣級別採用不同的顏色,統計不一樣級別出現的次數。oop
上面的例子中,咱們能夠看到,工具一共收集了 99 幀,最大耗時的一幀花了119ms,平均耗時:32.9 ms,總耗時:3259.5 ms。其中認爲有 40 幀流暢,25 幀良好,38 幀輕微卡頓,6 幀卡頓。post
看到上面的功能可能有人有疑惑,你這功能咋和 PerformanceOverLay 這麼相似?
首先,我在使用 PerformanceOverLay 的時候遇到了一點問題:
如圖,PerformanceOverLay 上分別爲咱們展現了構建(UI)耗時和渲染(GPU)耗時。
我遇到的第一個問題是,由於咱們在判斷流暢度的時候,每每是看一幀的總耗時。這樣拆分以後,一幀的耗時變成了上下的和,對我而言很不直觀。
其次,這裏面提供最大耗時
或者平均耗時
並不能很好的幫助咱們量化頁面的流暢程度。由於這個統計過程,會直接將一幀的耗時進行平均,這就帶來一個問題。咱們知道對於60刷新率的設備,兩幀的間隔時間最小應該是 16.7ms,而 PerformanceOverLay 的收集過程沒有對數據過濾,會出現一幀耗時小於 16.7ms,這就致使平均數據可能偏低。(下圖平均一幀耗時爲:10.6ms 60HZ設備)
其實這樣來看,DoKit是一個不錯的選擇
但DoKit一樣沒有對最小幀耗時作過濾,也會出現平均耗時偏低的狀況。同時,沒有更多的數據輔助評估頁面的流暢程度。
上面我遇到的狀況,不必定是問題,只是我在使用過程當中以爲不太直觀,不太方便。
所以開發了這個工具,該工具具備如下特色
同時支持設置最大采集幀數
我在上一期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的設備有意義。而且將流暢度劃分爲瞭如下等級:
並統計出現的次數,你能夠根據這幾項數據,對比優化先後的數據,得出性能的提高狀況;固然也能夠制定一個理想的流暢度。例如:流暢的幀數佔統計幀數的90%,或者卡頓的幀數不超過5次。
dependencies: fps_monitor: ^1.12.13-1
有兩處接入點
(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,
複製代碼
builder: (ctx, child) =>
CustomWidgetInspector(
child: child,
),
複製代碼
在完成了上述步驟以後,你只須要啓動app,該工具只會在profile/debug模式下集成,在你的右下角會出現一個 ⏯ 按鈕,點擊開始記錄,再次點擊顯示數據。
若是想要結束採集,點擊面板中的中止監聽便可。
若是你想採集更多的幀,能夠經過kFpsInfoMaxSize
設置
目前這個項目是基於 Flutter 1.12.13 分支進行開發,若是你在接入項目中遇到了了兼容性問題,歡迎評論區留言或者公衆號私信我。固然更加歡迎各位直接PR~
可能你會對這個工具的檢測原理感興趣,那我們再來嘮兩句原理。
WidgetsBinding.instance.addTimingsCallback(monitor);
複製代碼
Flutter 會在每幀完成繪製後,會將耗時進行回調。耗時體如今三個變量上:一、構建時間;二、繪製時間;三、總時間。當你點擊 ⏯ 按鈕的時候,工具便開始採集耗時信息。
其實對於 Flutter 相關的渲染調度,推薦你們看看 SchedulerBinding
,裏面寫得再詳細不過。
顯示 Fps 的頁面比較簡單,直接經過 OverlayState 插入便可。若是你不太熟悉 Overlay 能夠把它理解成浮窗。其中的表格繪製經過使用 DoKit 的自定義畫筆實現,固然也可替換成各類開源的圖表庫。
若是你以爲這個工具還不錯,點個贊支持一下吧~
上一期文章發佈以後取得了很是好的數據
也讓我短暫的享受了下做者榜單榜一的體驗(如今已經不在了 QAQ)
感謝各位的支持!!!和你們同步一下,爲了確保開源的質量,不讓你們在使用過程當中添堵,目前 BKListView 還在處於測試中(上週剛發現一個 BUG  ̄□ ̄|| 不過已修復),完成後根據公司相關流程再進行開源~ 我會持續跟進,有進展會在公衆號和掘金上同步更新。
整個開發過程當中明顯的感受到了,源碼閱讀的重要性,若是沒有前期大量的源碼積累,整個設計過程當中也不會有這樣一些奇奇怪怪的思路。因此下一個階段,我任會持續的和你們一塊兒有方向計劃的分享源碼,但願咱們都能一塊兒進步。