Litho學習--Litho 簡介

背景介紹

Litho 是 FaceBook 2017年上半年開源的聲明式UI渲染框架。

為什么 Facebook 要開發(fā) Litho 喂饥?

APP中最常見的UI表現(xiàn)形式就是各種內(nèi)容豐富的Feed流置尔,比如各種新聞流杠步,圖片流。對于這些滾動列表榜轿,如何能夠保證流暢地滑動幽歼?

為了保證頁面滾動流暢,需要程序在1秒內(nèi)渲染60幀的數(shù)據(jù)才能保證頁面不卡頓差导,也就是在每16ms內(nèi)把需要顯示的幀畫在屏幕上试躏,否則就可能引起掉幀猪勇。

Android 系統(tǒng)是如何解決這個問題的设褐?

Android 系統(tǒng)中提供的滾動列表就是我們常見的 RecyclerView , RecyclerView 用于動態(tài)顯示大量數(shù)據(jù)集的列表,僅僅在屏幕中顯示有限的幾個條目泣刹,對于滑出屏幕的條目進行復用助析。

當某個條目第一次被顯示在屏幕上時,RecyclerVeiw 會讓 Adapter 新填充一個 View 顯示在屏幕上椅您。當用戶開始滾動列表的時候外冀,RecyclerView 會檢查是否有 Item 滾出屏幕,滾出屏幕的 View 會被放在pool中備用掀泳。當隨后需要再顯示這個 View 的時候雪隧,再從 pool 中取出來,讓 Adapter 用新數(shù)據(jù)對這個 View 顯示的數(shù)據(jù)進行更新员舵。

RecyclerView 在一幀內(nèi)都做了什么脑沿?

當需要在屏幕上顯示一個新的條目時,如果 pool 中沒有马僻,就新填充一個 View庄拇,然后更新 View 的數(shù)據(jù),之后是 measure韭邓,layout 措近, draw,所有這些都需要在 16ms 內(nèi)完成女淑。

那么問題來了:

  • 如果列表中 Item 的類型很多瞭郑,該怎么處理?
  • 如果單個 Item 比較復雜鸭你,既有圖片屈张,又有視頻我抠,還有各種文字鏈接的情況?

對于多種數(shù)據(jù)類型袜茧,RecylerView 中采用 ViewType菜拓,每一種ViewType 會分配一個 pool 。當 ViewType 大量增加笛厦,滾動列表的時候纳鼎,每一幀的數(shù)據(jù)里就可能更多地涉及到 View 的填充,View 的分配操作是個重操作裳凸,比較耗費資源贱鄙,也就是說 ViewType越多,就越有可能發(fā)生掉幀姨谷。另外在內(nèi)存上逗宁,那些使用頻率低的 ViewType 對應的 pool ,會一直存在于內(nèi)存中梦湘,內(nèi)存使用效率變低瞎颗。

如果 Item 本身比較復雜,想要提升性能捌议,就要對 itemview 進行優(yōu)化哼拔,比如靜態(tài)的 layout 優(yōu)化,減少布局層數(shù)瓣颅,或者 自定義layout 倦逐,但同時又帶來難以維護的問題。

RecyclerView 多類型復用

Litho 是如何解決上述問題的宫补?

1. Async Layout 異步布局

采用 Yoga 這個布局引擎 把 measure 和 layout 放到后臺線程檬姥。在ReactNative中也是用的Yoga,Yoga 是一種脫離于Android 系統(tǒng)的高效布局引擎粉怕,實現(xiàn)了 FlexBox 布局規(guī)范健民。

異步布局的意思就是提前在后臺線程渲染畫面,要在16ms內(nèi)進行measure斋荞,layout 荞雏,draw 三個必須又耗時的操作,Android 傳統(tǒng)的做法是把所有這些操作放在 MainThread 平酿,Litho 沒有這個限制凤优,Litho 使用 Yoga 渲染組件,把 measure 和 layout 放在后臺線程蜈彼,在新一幀到來之前提前在后臺線程中計算出組件的大小和位置筑辨,除了 Yoga 之外,如何保證線程安全幸逆,Litho 這里采用了不可變的聲明式 API 棍辕,使組件自然而然地保持了線程安全暮现,使得后臺渲染變得可行。


Android Threading Model
Litho Threading Model 1st

除此之外楚昭,現(xiàn)在我們已經(jīng)節(jié)省了主線程的時間栖袋,還可以進一步進行優(yōu)化。如果一幀有時間空余的話抚太,可以提前 draw 下一幀的內(nèi)容塘幅。這個是用 DisplayList 實現(xiàn)的, DisplayList 在Android系統(tǒng)中用來保存 openGL commands ,提前創(chuàng)建和編譯 Displaylists尿贫,需要顯示這個組件的時候电媳,只需要執(zhí)行里面的命令就可,不需要再進行編譯庆亡。(DisplayList is a group of openGL commands(已被保存匾乓,編譯) for later execution)


Litho Threading Model 2nd

2. View Flattering 鋪平View層次

好處:既減少了內(nèi)存使用,也減少了GC的頻率又谋。

在不改變顯示內(nèi)容的基礎上拼缝,鋪平 View 結構可以減少 View 的個數(shù)


View Flatterning

a. 容器處理的優(yōu)化:

Android 里面有很多容器,如果下圖中的 Row 和 Column 不需要畫背景的話搂根,真正需要顯示在屏幕上的組件只有一個圖片加上兩個文本,那么就可以把 Row 和 Column 這兩個容器刪掉珍促。Litho 會去檢測容器是否影響組件的繪制,如果不影響就刪掉剩愧。由于使用了 Yoga,因為 Litho 允許 layout 過程中不使用 Android Views娇斩,可以提前得知在繪制組件的時候是否需要容器仁卷。


Container

b. View層面處理的優(yōu)化:

如果 Row 和 Column 這兩個容器消失了,那對于這個圖片和兩個文本要如何處理犬第?

標準的Android系統(tǒng)锦积,圖片使用 ImageView,文本使用 TextView
Litho 中的實現(xiàn)使用 Drawables歉嗓,輕量級丰介,不會有 View 的內(nèi)存和性能負擔,使用 Drawables 讓Litho進一步減少 View 的層數(shù)鉴分。


View

3. Incremental Recycling 增量復用

Android ReyclerView 的復用是基于 ViewType 的哮幢,假設有上百個ViewType,各種文章文本視頻圖片組合在一起志珍,每個 Type 分配一個Pool橙垢,那將會有上百個 pool ,會對內(nèi)存造成負擔伦糯。

RecylerView 多類型復用
Litho中的細粒度復用

每個Item都是由一些核心組件構成的柜某,文本嗽元,圖片,視頻等喂击,只是不同的 Item 只是對這些核心組件進行不同的組合剂癌。不把每個 Item 的內(nèi)容看成一個整體,而是把 Item 拆分成各個核心組件翰绊。
當一個 Item 滾出屏幕珍手,就把這個 Item 分解成各個核心組件,每種核心組件放到一個 Pool 辞做,當顯示一個新的 Item 的時候琳要,再把這些組件進行重新組合。

更進一步的優(yōu)化:
因為我們不把一個 Item 當成一個整體秤茅,所以當這個 Item 滾出屏幕的時候稚补,也不用等整個 Item 滾出屏幕的時候再回收,只需要當每一個核心組件滾出屏幕就可以進行回收框喳。
下面這個例子课幕,當上面 Item 中的一部分移出屏幕,頭像和標題部分已經(jīng)被回收了五垮,不需要整個 Item 滾出屏幕乍惊,這些組件可以更快地回收和復用,以減少核心組件的數(shù)量放仗。

Incremental Recycling

參考

2017 Facebook F8

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末润绎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诞挨,更是在濱河造成了極大的恐慌莉撇,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惶傻,死亡現(xiàn)場離奇詭異棍郎,居然都是意外死亡,警方通過查閱死者的電腦和手機银室,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門涂佃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜈敢,你說我怎么就攤上這事辜荠。” “怎么了扶认?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵侨拦,是天一觀的道長。 經(jīng)常有香客問我辐宾,道長狱从,這世上最難降的妖魔是什么膨蛮? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮季研,結果婚禮上敞葛,老公的妹妹穿的比我還像新娘。我一直安慰自己与涡,他們只是感情好惹谐,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驼卖,像睡著了一般氨肌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酌畜,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天怎囚,我揣著相機與錄音桥胞,去河邊找鬼。 笑死贩虾,一個胖子當著我的面吹牛催烘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缎罢,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼伊群,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了屁使?” 一聲冷哼從身側響起在岂,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛮寂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體易茬,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡酬蹋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了抽莱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片范抓。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖食铐,靈堂內(nèi)的尸體忽然破棺而出匕垫,到底是詐尸還是另有隱情,我是刑警寧澤虐呻,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布象泵,位于F島的核電站寞秃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏偶惠。R本人自食惡果不足惜春寿,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忽孽。 院中可真熱鬧绑改,春花似錦、人聲如沸兄一。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽出革。三九已至造壮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蹋盆,已是汗流浹背费薄。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栖雾,地道東北人楞抡。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像析藕,于是被迫代替她去往敵國和親召廷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349