雖然Flutter號稱能夠媲美原生的app應用,但在複雜的App中,也是會遇到一些性能問題,所以該如何避免性能問題並且進行優化就很重要,接下來介紹一些常見的優化。
build()執行時是會使他的子widget重新構建,所以要最小化Widget,讓要重建的widget減少
當build()中的Widget要被重建時,會使build()中返回的Widget樹變大,導致重建的Widget數變多
當我們用const
定義好了一個instance,那麼其它地方再次使用此instance時,則會直接從常量池裡取,透過這樣的方式降低RAM的損耗
當構建一些長期不會進行修改的Widget時,盡量使用const widget。當父widget更新了,子widget也不會重新進行rebuild。ex.loading widget...等
當不想要顯示任何內容時,我們可以使用null,來降低構建成本。如果一定要使用widget的話,使用SizedBox.shrink
而不是Container
在構建具大量的grid或list時,盡量避免使用ListView(children: [],)
以及GridView(children: [],)
,使用此種方式,會讓列表中的所有項目一次性繪製出來。
建議使用ListView和GridView的builder
方法,他們只會繪製可見的列表內容。(也就是對列表採用了懶加載而不是直接一次性創建所有的子 Widget) ex.ListView.builder(itemCount: ..., itemBuilder: (context, index))
以及GridView.builder
...等
itemExtent
或prototypeItem
(兩者只能擇一)使用itemExtent
比讓子組件自己決定自身長度會有更好的性能。這是因為指定itemExtent後,滾動系統可以提前知道列表的長度,而無需每次構建子組件時都去再計算一下,尤其是在滾動位置頻繁變化時,使滾動系統需要頻繁去計算列表高度
而如果我們知道列表中的所有列表項長度都相同但不知道具體是多少,這時我們可以指定一個prototypeItem,並且可滾動組件會在layout時計算一次它延主軸方向的長度,來預先知道所有列表項的延主軸方向的長度
image
或大資源物件的話,透過addAutomaticKeepAlives
和addRepaintBoundaries
來降低memoryListView不會自動清除屏幕以外的item,也就是如果item裡有那些大圖,那麼它將會消耗非常多的內存,透過addAutomaticKeepAlives以及addRepaintBoundaries來讓flutter自動做回收,雖然會占用更多的計算資源(CPU/GPU),但能降低你的memory資源。
addAutomaticKeepAlives: 是否將每個child包裝在AutomaticKeepAlive中。(lazy list中的child一般被包裝在AutomaticKeepAlive小部件中,以便child可以使用 KeepAliveNotifications來保存他們的狀態,否則他們會在屏幕外被GC)
addRepaintBoundaries: 該屬性表示是否將列表項包裹在RepaintBoundary組件中。(將列表項包裹在RepaintBoundary中可以避免列表項不必要的重繪,但是當列表項重繪的開銷非常小時(ex.較短的文本),不添加RepaintBoundary反而會更高效)
ref:
今天簡單的介紹了如何簡易優化我們的app,我們明天見