Flutter渲染及性能優(yōu)化

背景

說到flutter的圖像渲染性能,首先我們來看一下iOS和Android的渲染過程

原生渲染流程圖

在安卓中耗時(shí)的操作是測(cè)量,布局,繪制等都是由view負(fù)責(zé)的,iOS也非常的相似由UIview負(fù)責(zé),大部分時(shí)間在遍歷UIview樹的不同節(jié)點(diǎn)

相比于原生Flutter在渲染的流程上并不會(huì)遜色

flutter渲染流程圖


如果在fultter中找到和UIview和view相似的部件那就是RenderObject,有狀態(tài),有長(zhǎng)期生命,和原生不同的是他只有一個(gè)布局功能的函數(shù)performLayout();

? /// In implementing this function, you must call [layout] on each of your

? /// children, passing true for parentUsesSize if your layout information is

? /// dependent on your child's layout information. Passing true for

? /// parentUsesSize ensures that this render object will undergo layout if the

? /// child undergoes layout. Otherwise, the child can change its layout

? /// information without informing this render object.

? @protected

? void performLayout();


RenderObject擁有面積更小的API,相比于安卓的250和iOS的500個(gè),他只有50個(gè)比較簡(jiǎn)單

查看flutter的渲染性能.

在Android Studio 中使用Profile模式運(yùn)行(像碼表一樣的按鈕),如果使用command line 來運(yùn)行的話可以使用flutter run --profile來運(yùn)行,在查看性能時(shí)一定要使用真機(jī)來運(yùn)行,不要使用模擬器,第一模擬器使用的軟件渲染,第二模擬器是debug模式,所以并不能真實(shí)的反應(yīng)出每一幀的渲染時(shí)間


performance功能展示

如果想顯示在手機(jī)上可以使用show performance overlay


有左邊的一個(gè)Container,從圖中可以看出wieget和element是一一對(duì)應(yīng)的,componetElement是沒有自己的RenderObnject的,他是用來做組合的,并不會(huì)參與布局和繪制,如果對(duì)componetElement再進(jìn)行分類就會(huì)出現(xiàn)StatelessElement和StatefulElement,對(duì)應(yīng)的widget就是?StatelessWidget和StatefulWidget

build階段

從text('data')如果變成text('A'),build的開始,widget是不可改變的,只能將widget拋棄創(chuàng)建新的樹(可以把widget看成是element的描述),下一步對(duì)上一幀的Element樹做遍歷,最重要的方法

Element.updateChild();

方法通過查看element的子節(jié)點(diǎn),如果子節(jié)點(diǎn)和之前的類型一樣那么就繼續(xù)向下遍歷,如果不一樣就會(huì)將element進(jìn)行更新,如果是Componet類型就可以statelessWidget和statefulWidget做更新叫build,他會(huì)提供一個(gè)DecorateBox,拿到decorateBox做進(jìn)一步的遍歷,decorateBox是一個(gè)RenderObject類型,讓RenderObjectwidget對(duì)于RenderObject做更新,通過updateRenderObject();方法,按照這樣的邏輯遍歷到最后只有Text需要被更新,那么減少遍歷就會(huì)優(yōu)化每一幀的時(shí)間

在Android Studio可以使用Open Observatory 打開觀測(cè)臺(tái)工具



通過觀測(cè)臺(tái)可以查看內(nèi)存,以及CPU的工作情況,通過timeline功能可以查看各階段耗時(shí)情況,在任意位置添加debugProfileBuildsEnabled = true;

可以在timeline中看到我們遍歷了很多節(jié)點(diǎn),我們只改變了一個(gè)text卻要編了非常龐大的樹,確實(shí)存在效率問題

那么如何能提高Build的遍歷效率呢?


1.降低遍歷的出發(fā)點(diǎn)

沒有必要從頂層開始遍歷,應(yīng)該是從text出現(xiàn)的地方開始遍歷,那么我們修改代碼,將text單獨(dú)提取出來


那么再來看一下遍歷的效率,非常好的降低了遍歷的數(shù)量提高效率


2.停止樹的遍歷

? ?將上一幀中的子樹從上一幀切下來直接放到新的一幀上,SlideTransition的每一幀都會(huì)對(duì)自己做比較更新做改變,如果加入了child那么他的子樹就不會(huì)跟著,SlideTransition做比較更新

SlideTransition(

...

child: Row(

children: <Widget>[],

))

提高Paint流程效率

在非常復(fù)雜的頁面情況下,會(huì)形成多個(gè)圖層的疊加,那么圖層也會(huì)形成自己的樹,在繪制一個(gè)widget時(shí),整個(gè)界面的圖層都會(huì)跟著重新繪制


在iOS重每個(gè)UIview都擁有自己的CALayer,雖然會(huì)增加內(nèi)存但是卻可以提高效率,安卓中每一幀都將會(huì)重新繪制所有的節(jié)點(diǎn)

Flutter則會(huì)在每個(gè)分界線都形成自己的圖層如果一個(gè)圖層只是自己更新而不會(huì)影響其他圖層那么可以增加一個(gè)RepaintBoundary來創(chuàng)造一個(gè)自己的圖層

RepaintBoundary(

child: Text('A'),

)

這時(shí)候我們來看圖層的更新只會(huì)更新自己節(jié)點(diǎn)的圖層


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漾脂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子九火,更是在濱河造成了極大的恐慌稼稿,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件者吁,死亡現(xiàn)場(chǎng)離奇詭異窘俺,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)复凳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門瘤泪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人育八,你說我怎么就攤上這事对途。” “怎么了髓棋?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵实檀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我按声,道長(zhǎng)膳犹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任签则,我火速辦了婚禮须床,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怀愧。我一直安慰自己侨颈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布芯义。 她就那樣靜靜地躺著哈垢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扛拨。 梳的紋絲不亂的頭發(fā)上耘分,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音绑警,去河邊找鬼求泰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛计盒,可吹牛的內(nèi)容都是我干的渴频。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼北启,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼卜朗!你這毒婦竟也來了拔第?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤场钉,失蹤者是張志新(化名)和其女友劉穎蚊俺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逛万,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泳猬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宇植。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片得封。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖当纱,靈堂內(nèi)的尸體忽然破棺而出呛每,到底是詐尸還是另有隱情,我是刑警寧澤坡氯,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站洋腮,受9級(jí)特大地震影響箫柳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啥供,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一悯恍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伙狐,春花似錦涮毫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至唉侄,卻和暖如春咒吐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背属划。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工恬叹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人同眯。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓绽昼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親须蜗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子硅确,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容