提高Flutter性能的小技巧!(一)
這篇寫於 2022 年。工具和 API 變化很快,部分步驟可能已經不適用。
創造高品質的用戶體驗
使用 Widget 代替 function-widget#
- 使用 StatefulWidget、StatelessWidget 可以在 WidgetTree 瀏覽與查詢
- App 崩潰時在stack trace上查看
Bad#
Good#
盡量使用 const#
- 宣告
const,避免重新繪製與造成多餘的效能消耗,讓 Flutter 僅重建應該更新的元件 - 使用相同的 Widget 時,可以節省記憶體
使用 nil Widget 代替無意義 SizedBox 與 Container#
- nil 為第三方套件
- nil 元件為簡單的
Element,在創建的時候什麼都不做,擁有最小的效能影響 - 不適用於可以包裹多個子元件的元件,例如
Rows、Columns等
使用狀態管理套件#
這些套件提供穩定的架構確保開發流程,更可以有效幫助資料與畫面刷新,而不是重建所有元件
避免 AnimationController 使用 setState 更新動畫#
- 不要在 addListener() 裡使用 setState() 更新
- 錯誤的使用方式將導致重建整個 UI,影響到其他元件,並使動畫延遲、卡頓
- 盡量使用
AnimatedBuilder刷新動畫
不要使用 Opacity 搭配 AnimationBuilder#
- 改變不透明度本身是一個昂貴且耗效能的動畫
- 實現淡入淡出,使用
FadeTransition或AnimatedOpacity FadeTransition不會觸發 Build 繪製UI,Build 通常會在 Layout 和 Animation 之間進行,使用 GPU 的片段著色器(fragment shader)實現漸變不透明度
Bad#
Good#
- FadeTransition 直接透過 RenderObject 優化效能,沒有產生Element
- Build 過程來自 Element
or
使用 Keys 提高效能#
- 更好地識別 Widget
- 提升4倍以上的效能
提醒#
ValueKey讓程式碼看起來有點雜亂GlobalKey禁止濫用,看情況與作用區域決定
設置 ListView 的 itemExtent#
- 固定列表上的子元件長度,如果是垂直滾動代表是高度; 如果是水平滾動代表是寬度
- 有助於 Flutter 計算 ListView 的滾動位置,提前知道列表的長度,而不是創建時計算每個元件的高度(尤其是在滾動位置頻繁變化時),使性能更好
ListView 載入高像素圖片#
// 預設為true,讓每個item的狀態保持活動狀態
addAutomaticKeepAlives: true
// 預設為true,每個item都用RepainBoundry包裝,它只繪製一次以獲得更高的性能
addRepaintBoundaries: true
- ListView 保持 item-widget 處於活動狀態,並且它不會再重新繪製
- 在使用者操作滾動時,原本的item雖然沒有在畫面上顯示,但是一樣存在,滾動回來後直接顯示,不需要繪製消耗資源,為了確保滑動順暢
但是#
加載大量圖片(高像素圖片)後,因為沒有被釋放肯定會消耗大量內存,最終可能會使應用崩潰。可以簡單地禁用它們,這樣不可見的 item-widget 將被自動處理和被垃圾收集器回收。
提醒:將參數設置為 false,可能會導致使用更多 GPU 和 CPU 工作,因為重新繪製並管理狀態,但它可以解決記憶體問題,並且獲得高效的畫面。
使用 for/while 代替 foreach/map#
For loops 是最快的,先緩存迴圈長度,這是計算時間最短的寫法
for 和 while,兩種倒序方式的性能會稍差一些
參考#
- https://docs.flutter.dev/perf/best-practices
- https://itnext.io/flutter-performance-tips-4580b2491da8
- https://itnext.io/flutter-performance-tips-part-2-7e37af5b0690
- https://medium.com/@deepaklohmod6789/top-5-tips-for-flutter-performance-optimization-and-following-best-practices-to-build-your-next-abe3b8c94fcd
- https://blog.codemagic.io/how-to-improve-the-performance-of-your-flutter-app./#dont-split-your-widgets-into-methods
其他文章#
- What are Async and Isolates in Flutter?
- Flutter 3 有什麼新東西?
- Riverpod 輕鬆學,原來這麼好用!
- Riverpod 輕鬆學(二),一些進階用法!
- 實作 Discord 機器人取得 NFT 地板價
關於我#
- Github:https://github.com/chyiiiiiiiiiiii
- Linkedin:https://www.linkedin.com/in/yiichenhi/
- Youtube:Yii
- Youtube:一起饅頭(美食頻道)
- Instagram:yiichenhi
- Email:ab20803@gmail.com
贊助#
謝謝你!這是一個很長的文章而且你花費時間看完,真的非常感謝。
還有一件事, 如果覺得文章不錯可以贊助我,讓我有更多的動力和熱情分享 學習筆記和生活!請我喝一杯咖啡吧~
最後#
希望有幫助到你/妳,歡迎追蹤我,方便瀏覽最新的文章,也請別忘記給我拍手哦 (最多可以達到50次)!
本文原刊登於 Medium。



