Flutter的widget渲染正常情況下一般可以達到60fps以上,作為跨平台語言為甚么有如此優勢?
- 它基於Skia引擎直接繪制
- Skia經過Google團隊優化后,性能明顯提升,如抗鋸齒能力就得到了很好的改善
但這並不意味着怎么寫都可以達到這個水平,實際開發時需要綜合考慮各方面的因數,如業務邏輯臃腫導致
WidgetTree
龐大,不夠合理的狀態刷新導致大兩部必要的Widget被重新構建,各種插件的注冊和通信沒能很好的處理,UI線程的大量IO讀寫,等等這些都會給項目帶來致命的缺陷,最終引發出的問題就是頁面卡頓,卡死,嚴重影響用戶體驗。
Flutter性能問題主要集中在GPU線程和UI線程,需要對圖層的構建,在了解如何使用Flutter性能檢測工具之前我們需要對它的運行模式有寫基本的了解,Flutter提供了Observatory
用於檢測app性能指標.
Flutter性能檢測工具-Observatory
observatory: 在
engine/shell/testings/observatory
可以找到它的具體實現,它開啟了一個ServiceClient
,用於獲取dartvm
運行狀態.flutter app啟動的時候會生成一個當前的observatory服務器的地址An Observatory debugger and profiler on iPhone SE (2nd generation) is available at: http://127.0.0.1:58662/4Qp1i3ZFmCs=/
在瀏覽器中打開,可以看到這個功能圖
Observatory-Debugger
debugger: 有一個debug控制台,需要通過命令去控制,主要是對堆棧的操作和isolate,vm狀態的管理
List of commands: break - Add a breakpoint by source location or function name (hotkey: [F8])
clear - Remove a breakpoint by source location or function name (hotkey: [F8])
cls - Clear the console
continue, c - Resume execution of the isolate (hotkey: [F7])
delete - Remove a breakpoint by breakpoint id
down - Move down one or more frames (hotkey: [Page Down])
finish - Continue running the isolate until the current function exits
frame, f - Set the current frame
help - List commands or provide details about a specific command
info - Show information on a variety of topics
isolate, i - Switch, list, rename, or reload isolates
log - Control which log messages are displayed
next, n - Continue running the isolate until it reaches the next source location in the current function (hotkey: [F9])
next-async - Step over await or yield
next-sync - Run until return/unwind to current activation.
pause - Pause the isolate (hotkey: [Ctrl ;])
print, p - Evaluate and print an expression in the current frame
refresh - Refresh debugging information of various sorts
reload - Reload the sources for the current isolate
rewind - Rewind the stack to a previous frame
set - Set a debugger option
step, s - Continue running the isolate until it reaches the next source location (hotkey: [F10]
up - Move up one or more frames (hotkey: [Page Up])
vm - Manage a Dart virtual machine
For more information on a specific command type 'help <command>'
For a list of hotkeys type 'help hotkeys'
Command prefixes are accepted (e.g. 'h' for 'help')
Hit [TAB] to complete a command (try 'is[TAB][TAB]')
Hit [ENTER] to repeat the last command
Use up/down arrow for command historyObservatory-Class Hierarchy
包括了所有的flutter framework相關的class繼承關系
Observatory-cup profile(table)
- cup profile: 查看當前cpu的使用率,詳細列出了每個堆棧占用的大小,支持關鍵字過濾搜索
- cup profile(table)
Observatory-allocation profile
- 查看內存分配
Observatory-allocation heap snapshot
- 查看堆區的快照信息,支持多種展現,可一很直觀的的看到某個類的占用空間(非常有用)
- tree map圖示,可以切換成class
## Observatory-Metrics
- 堆區分配的統計信息,對項目的內存泄漏檢查有一定的幫助
## Observatory-persistent handles
- 查看待處理繪制指令
Observatory-main
- main isolate的概覽信息,當前占用的資源信息,依賴的服務等
## Observatory-timeline
- 提供了多種選項分類統計api的調用時間長
- 通過
flutter run --profile --trace-skia
來查看skia的調用情況,將文件導入,點擊上面窗口的load
- Flutter將每一幀錄制成SkPicture給Skia渲染,也可以通過捕捉Skp(SkPicture)進行分析,命令
flutter screenshot --type=skia
DevTools檢測
DevTools也提供了一些基本的檢測,具體的細節沒有Observatory
提供的完善.
下面的Timeline常見的示意圖,y軸承為每一幀渲染的基准線16ms
以下為UI線程耗時較長的build階段
展開Build CallTree,主要耗時發生在
updateChild
,子樹的構建占用了大量時間
除了UI Thread外,還包括了Raster Thread(GPU線程)的火焰圖,圖形可以放大和縮小,同樣可以看到每個過程的
參考鏈接
bilibi: https://www.bilibili.com/video/av63626119
observatory: https://github.com/flutter/engine/tree/master/shell/testing/observatory