使用 StatefulBuilder 進行局部更新
- 當
Widget tree
較大時,更新一個屬性導致整顆樹重建,這是很浪費效能的 - 使用 builder() 提供的
setState
來更新指定元件,而其他不相關的元件可以保持原樣
補充:適當的搭配 RepaintBoundary
來開發,讓Tree不花費過多成本在重建
適當的壓縮數據
壓縮後可節省記憶體,需要時再解壓縮並使用。
謹慎使用 saveLayer()
- 主要是用來呈現各種 UI 視覺效果,渲染形狀、透明度與重疊效果都會使用到
saveLayer()
- 調用
saveLayer()
會分配一個螢幕外緩衝區(offscreen buffer)
,並且將內容繪製到這裡,可能會觸發渲染目標的切換。渲染目標強制 GPU 臨時轉換工作流,然後再次將其引導回來,影響渲染的效果 - 有呼叫
saveLayer()
的元件, ShaderMask、ColorFilter 等 - Widgets 跟 Packages 可能有在使用,過多的使用可能造成卡頓
減少裁剪的使用
- Clipping 不會調用
saveLayer()
(除非使用Clip.antiAliasWithSaveLayer
),默認情況下裁剪被禁用(Clip.none
) - 要創建帶圓角的矩形,可以多使用
borderRadius
屬性去實現,而不要使用裁切矩形 - 避免在動畫中進行裁剪,盡量在執行動畫之前先裁剪圖像
在16毫秒內完成創建和顯示幀(Build and display frames)
- 創建和渲染在各別的線程上運行,如果要避免延遲,需在
16毫秒
或更短的時間內創建並顯示一幀。代表著在8毫秒
以內創建,並在8毫秒
以內渲染。 - 如果總渲染時間低於16毫秒,即使存在一些性能缺陷,也不必擔心性能,因為可能不會產生視覺差異
- 可以改善電池壽命和散熱問題
- 隨著120fps設備的普及,需要8毫秒內創建和顯示幀,以提供最流暢的體驗
- 在
Flutter Performance
窗口中,開啟Show widget rebuild information
選項,可幫助檢測幀的渲染和顯示時間是否有超過16毫秒
使用官方的 flutter_lints 套件
- 隱形的 code reviewer
- 即時檢查程式碼是否不符合規則、是否有風險、是否需要優化
- 可以自定義規則,符合自己專案的開發風格
- 套件持續更新、改版,代表有更強大的審查者在監看,維護專案的高品質
維持 Synchronous BuildContexts
- 因為UI在
build()
執行時是同步處理,但通常在跟使用者互動後(點擊按鈕…)有可能會觸發非同步任務,如果任務處理完後需要進行一些context
的存取和操作,必須確保 Widget tree 是否創建完成並與 element 進行綁定,context 本身是 element 的配置 - 一般畫面、元件在執行動畫、滾動、拖動等操作的時候,Widget會頻繁銷毀跟創建,存活的時間約為50ms,而過程中Widget對應的 element 可能已經離開 element tree,如果在Widget創建期間進行 context 操作,尤其是在非同步任務結束後進行,可能就會出錯和崩潰
- context操作包含
of(context)
靜態函式的 InheritedWidget 存取
Bad
flutter_lints
會顯示提醒文字,說明不要在執行非同步任務後存取BuildContexts。
Good
需要在存取BuildContexts之前,先透過 mounted
確保(element)已經綁定到 State 上了,如果沒有則不進行後續處理。
還有另一種方式,先儲存需要的物件或資源,等任務處理完後再透過剛剛暫存的物件進行操作。
適當的存取 MediaQuery.of(context)
- 通常都會在
build()
的一開始取得螢幕長寬,接著設置需要創建的Widget tree,但是只要狀態有更新或是其他原因導致 build() 頻繁重建、更新的話,就會持續存取 MediaQuery。而我們應該只需要在螢幕和畫面大小有變更時重新取得數據就好 - 一旦 MediaQuery 有任何更新都會觸發
didChangeDependencies()
,可以在這裡存取 MediaQuery,取得螢幕大小後儲存到記憶體,接著widget在創建時就可以透過變數取得最新的螢幕數據
補充:當有存取InheritedWidget時,都需要注意操作的地方,避免多餘的成本消耗
保持 Flutter 為最新版本
在每個版本中,Flutter 都進行了許多優化,效能也提高許多,所以不要忘記持續追蹤與更新。
其他文章
- “freezed” makes model class strong and easily
- 提高Flutter性能的小技巧!(一)
- 提高Flutter性能的小技巧!(二)
- What are Async and Isolates in Flutter?
- LoadBalancer is optimization for Isolates in Flutter
- Flutter 3 有什麼新東西?
- Riverpod 輕鬆學,原來這麼好用!
- Riverpod 輕鬆學(二),一些進階用法!
關於我
- Github: https://github.com/chyiiiiiiiiiiii
- Linkedin: https://www.linkedin.com/in/yiichenhi/
- Youtube: Yii
- Youtube: 一起饅頭(美食頻道)
- Instagram: yiichenhi
- Email: ab20803@gmail.com
贊助
謝謝你!這是一個很長的文章而且你花費時間看完,真的非常感謝。
還有一件事, 如果覺得文章不錯可以贊助我,讓我有更多的動力和熱情分享 學習筆記和生活!請我喝一杯咖啡吧~
最後
希望有幫助到你/妳,歡迎追蹤我,方便瀏覽最新的文章,也請別忘記給我拍手哦 (最多可以達到50次)!