iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
自我挑戰組

30天學習flutter系列 第 25

25.關於flutter的優化 (一)

  • 分享至 

  • xImage
  •  

雖然Flutter號稱能夠媲美原生的app應用,但在複雜的App中,也是會遇到一些性能問題,所以該如何避免性能問題並且進行優化就很重要,接下來介紹一些常見的優化。

布局面

build()

  • 最小化重複和昂貴的build()方法工作

build()執行時是會使他的子widget重新構建,所以要最小化Widget,讓要重建的widget減少

  • 避免再build()中使用大量的Widget

當build()中的Widget要被重建時,會使build()中返回的Widget樹變大,導致重建的Widget數變多

  • 盡可能地使用 const

當我們用const定義好了一個instance,那麼其它地方再次使用此instance時,則會直接從常量池裡取,透過這樣的方式降低RAM的損耗

  • 對一些不常用的組件使用const constructor

當構建一些長期不會進行修改的Widget時,盡量使用const widget。當父widget更新了,子widget也不會重新進行rebuild。ex.loading widget...等

  • 當不想要顯示時,可以使用null而不是Container()/SizedBox()

當不想要顯示任何內容時,我們可以使用null,來降低構建成本。如果一定要使用widget的話,使用SizedBox.shrink而不是Container

List和Grid

  • List和Grid優化

在構建具大量的grid或list時,盡量避免使用ListView(children: [],)以及GridView(children: [],),使用此種方式,會讓列表中的所有項目一次性繪製出來。
建議使用ListView和GridView的builder方法,他們只會繪製可見的列表內容。(也就是對列表採用了懶加載而不是直接一次性創建所有的子 Widget) ex.ListView.builder(itemCount: ..., itemBuilder: (context, index))以及GridView.builder...等

  • 對於非常大的長列表,記得在ListView中使用itemExtentprototypeItem(兩者只能擇一)

使用itemExtent比讓子組件自己決定自身長度會有更好的性能。這是因為指定itemExtent後,滾動系統可以提前知道列表的長度,而無需每次構建子組件時都去再計算一下,尤其是在滾動位置頻繁變化時,使滾動系統需要頻繁去計算列表高度

而如果我們知道列表中的所有列表項長度都相同但不知道具體是多少,這時我們可以指定一個prototypeItem,並且可滾動組件會在layout時計算一次它延主軸方向的長度,來預先知道所有列表項的延主軸方向的長度

  • ListView item中有image或大資源物件的話,透過addAutomaticKeepAlivesaddRepaintBoundaries來降低memory

ListView不會自動清除屏幕以外的item,也就是如果item裡有那些大圖,那麼它將會消耗非常多的內存,透過addAutomaticKeepAlives以及addRepaintBoundaries來讓flutter自動做回收,雖然會占用更多的計算資源(CPU/GPU),但能降低你的memory資源。

addAutomaticKeepAlives: 是否將每個child包裝在AutomaticKeepAlive中。(lazy list中的child一般被包裝在AutomaticKeepAlive小部件中,以便child可以使用 KeepAliveNotifications來保存他們的狀態,否則他們會在屏幕外被GC)

addRepaintBoundaries: 該屬性表示是否將列表項包裹在RepaintBoundary組件中。(將列表項包裹在RepaintBoundary中可以避免列表項不必要的重繪,但是當列表項重繪的開銷非常小時(ex.較短的文本),不添加RepaintBoundary反而會更高效)


ref:

Flutter Performance

今天簡單的介紹了如何簡易優化我們的app,我們明天見


上一篇
24.關於flutter的非同步處理(二)
下一篇
26.關於flutter的優化 (二)
系列文
30天學習flutter30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言