一.內(nèi)存優(yōu)化
1.識別出消耗多余內(nèi)存的圖片
Flutter Inspector
:點(diǎn)擊Highlight oversized images
肋演,會解碼出那些大小超過展示大小的圖片薪夕,并且系統(tǒng)會將其倒置突出顯示扇谣。
此類圖片會導(dǎo)致性能不佳,尤其是在低端設(shè)備上充活,并且當(dāng)有許多圖片(例如在列表視圖中)時亿眠,這種性能影響可能會增加。
如果圖片使用的大小至少比要求的大128KB会傲,則圖片被視為太大锅棕。
修復(fù)圖片:
<1>.解決此問題的最佳方法是調(diào)整圖片資源文件的大小,使其更小淌山。
<2>.如果這是不可能的裸燎,可以在加載圖片時使用cacheWidth
和cacheHeight
參數(shù),這使引擎以指定大小解碼該圖片泼疑,并減少內(nèi)存使用(解碼和存儲仍然比縮小圖片資源本身更昂貴)德绿。
2.避免在快速滾動時加載圖片
使用官方的ScrollAwareImageProvider
組件,會在列表快速滑動時中斷圖片的下載和解碼退渗,從而減少不必要的內(nèi)存占用移稳。
雖然這種方法不能100%解決圖片加載時 OOM 的問題,但是很大程度優(yōu)化了列表中的圖片內(nèi)存占用氓辣,官方提供的數(shù)據(jù)上看理論上可以在原本基礎(chǔ)上節(jié)省出 70% 的內(nèi)存秒裕。
3.不要使用shrinkWrap
為true
Flutter
團(tuán)隊(duì)將從滑動控件里面棄用shrinkWrap
屬性,因?yàn)閳F(tuán)隊(duì)覺得現(xiàn)階段的開發(fā)人員大多數(shù)時候不知道它的實(shí)際含義钞啸,只是單純使用它解決問題几蜻,在使用過程中容易出現(xiàn)錯誤的性能損耗而不自知。
shrinkWrap:true
的時候体斩,在滑動控件內(nèi)部會采用一個特殊的ShrinkWrappingViewport
窗口進(jìn)行實(shí)現(xiàn)梭稚,ShrinkWrappingViewport
是調(diào)整自身大小去匹配主軸方向中Item
的大小,這種收縮的行為成本會變高絮吵,因?yàn)榇翱诖笮⌒枰ㄟ^Item
去確定弧烤。
shrinkWrap:true
會將列表所有的item
都構(gòu)建完成,盡管他們還遠(yuǎn)沒有在 ViewPort
展示出來蹬敲,所以shrinkWrap
讓ListView
失去了懶加載的作用暇昂,導(dǎo)致內(nèi)存性能問題。
4.addAutomaticKeepAlives
和addRepaintBoundaries
addAutomaticKeepAlives:true
表示將item
包裹在AutomaticKeepAlive
組件中伴嗡,當(dāng)item
滑出屏幕時不會被GC(垃圾回收)急波,會使用KeepAliveNotification
來保存其狀態(tài),從而在再次出現(xiàn)在屏幕的時候能夠快速構(gòu)建瘪校。這其實(shí)是一個拿空間換時間的方法澄暮,會造成一定程度的內(nèi)存開銷名段。
addRepaintBoundaries:true
表示將item
包裹在RepaintBoundary
組件中,當(dāng)列表滾動時泣懊,包裹在RepaintBoundary
中的item
可以避免重繪伸辟,當(dāng)item
重繪的開銷特別小時(比如一個顏色塊,一個較短的文本)馍刮,不添加RepaintBoundary
反而更高效信夫。
若禁用addAutomaticKeepAlives
和addRepaintBoundaries
,會在一定程度上優(yōu)化內(nèi)存渠退,但是這會影響渲染性能忙迁,需要在內(nèi)存和渲染性能之間權(quán)衡。
5.列表中的元素盡可能使用const
修飾
使用 const 相當(dāng)于將元素緩存起來實(shí)現(xiàn)共用碎乃,若列表元素某些部分一直保持不變姊扔,那么可以使用 const 修飾。
二.滾動優(yōu)化
1.指定列表項(xiàng)的固定高度
ListView
的itemExtent
屬性用于指定item
的固定高度梅誓,它告訴ListView
在構(gòu)建列表時使用固定大小的緩沖區(qū)恰梢。
如果知道item
的固定高度,可以講itemExtent
設(shè)置為該值梗掰,有利于Flutter
更有效的管理列表的布局嵌言,并且在滾動時可以提高性能
。
2.合理使用緩沖區(qū)
ListView
可以通過設(shè)置cacheExtent
來設(shè)置預(yù)先加載的內(nèi)容大小及穗。通過預(yù)先加載可以提升view
渲染的速度摧茴。但是這個值需要合理設(shè)置,并非越大越好埂陆。因?yàn)轭A(yù)加載緩存越大苛白,對頁面整體內(nèi)存的壓力就越大。