iOS 性能優(yōu)化_AsyncDisplayKit 初探

AsyncDisplayKit 是 Facebook 開源的用于保持 iOS 界面流暢的庫。

  1. ASDK 的基本原理



    ASDK 認為缕粹,阻塞主線程的任務,主要分為以上三大類纸淮,文本和布局的計算平斩、渲染、解碼咽块、繪制都可以通過各種方式異步執(zhí)行绘面,但 UIKit 和 CoreAnimation 相關操作必須在主線程執(zhí)行。ASDK 的主要任務侈沪,就是將這些任務從主線程挪走揭璃,而挪不走的,就盡量封裝優(yōu)化亭罪。

為了達成這一目標瘦馍,ASDK 嘗試對 UIKit 組件進行封裝



這是常見的 UIView 和 CALayer 的關系:UIView 持有 Layer 用于顯示,View 中的大部分顯示屬性實際上是從 Layer 映射而來的应役;Layer 的 delegate 是 UIView情组,當其屬性改變、動畫產生時箩祥,View 能夠得到通知院崇。UIView 和 CALayer 不是線程安全的,并且只能在主線程創(chuàng)建袍祖、訪問和銷毀底瓣。

![](http://upload-images.jianshu.io/upload_images/4653622-ace8647c111ee2d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/500)

ASDK 為此創(chuàng)建了 ASDisplayNode 類,包括了常見屬性(比如 frame/bounds/alpha/transform/backgroundColor/superNode/subNodes)等蕉陋,然后它用 UIView->CALayer 的方式捐凭,實現了 ASNode->UIView 這樣的一個關系。


當不需要響應觸摸事件時寺滚,ASDisplayNode 可以被設置為 layer backed,即 ASDisplayNode 充當了原來的 View 的功能柑营,節(jié)省了更多資源。
與 UIView 和 CALayer 不同村视,ASDisplayNode 是線程安全的官套,它可以在后臺線程創(chuàng)建和修改。Node 剛創(chuàng)建的時候蚁孔,并不會在內部新建 UIView 和 CALayer奶赔,直到第一次在主線程訪問 UIView 和 CALayer 屬性時,它才會在內部生成相應對象杠氢。當它的屬性(frame/transform)改變后站刑,它并不會立即同步到它持有的 View 或者 Layer 上,而是把改變的屬性保存到內部的一個中間變量鼻百,稍后需要的時候再通過某個機制一次性設置到內部的 View 和 Layer绞旅。

  1. ASDK 的圖層預合成
    有時候一個 Layer 會包含許多 sub-Layer摆尝,而這些 sub-Layer 并不需要響應觸摸事件,也不需要進行動畫和位置調整因悲。ASDK 為此實現了一個叫做 pre-composing 的技術堕汞,可以把這些 sub-layer 合成渲染為一張圖片。開發(fā)時晃琳,ASNode 已經替代了 UIView 和 CALayer讯检;直接使用各種 Node 并設置為 layer backed 后,ASNode 甚至可以使用預合成來避免創(chuàng)建內部的 UIView 和 CALayer卫旱。
    通過這種方式人灼,把一個大的層級,通過一個大的繪制方法繪制到一張圖上顾翼,性能會獲得很大提升投放。CPU 也避免了創(chuàng)建 UIKit 對象的資源消耗,GPU 避免了多張 Texture 合成和渲染的消耗适贸,更少的 bitmap 也意味著更少的內存占用跪呈。

  2. ASDK 異步并行開發(fā)
    自4S 開始,蘋果移動設備都已經是雙核 CPU 以上 取逾,充分利用多核的優(yōu)勢耗绿、并發(fā)執(zhí)行任務對保持界面流暢有很大作用。ASDK 把布局計算砾隅、文本排版误阻、圖片/文本/圖形渲染等操作都封裝成較小的任務,并利用 GCD 異步并發(fā)執(zhí)行晴埂。如果開發(fā)者使用了 ASNode 相關的控件究反,那么這些并發(fā)操作會自動在后臺進行,無需進行過多配置儒洛。

  3. Runloop 任務分發(fā)
    Runloop Work Distribution 是 ASDK 一個比較核心的技術精耐。ASDK 的介紹視頻和文檔中都沒有詳細介紹,但是網上關于 Runloop 的博客很多琅锻,在這里無需贅述卦停。


iOS 的顯示系統是由 VSync 信號驅動的,VSync 由硬件時鐘生成恼蓬,每秒發(fā)出60次(這個值取決于設備惊完,iPhone 上通常是 59.97 次)。iOS 圖形服務收到 VSync 信號后处硬,會通過 IPC 通知的 App 內小槐,App 的 Runloop 在啟動后會注冊對應的 CFRunloopSource 通過 math_port 傳過來的時鐘信號通知,隨后 Source 的回調會驅動整個 App 的動畫與現實荷辕。
Core Animation 在 Runloop 中注冊了一個 Observer凿跳,監(jiān)聽了 BeforeWaiting 和 Exit 事件件豌,這個 Observer 的優(yōu)先級是 200 0000,低于其他常見的 Observer控嗜。當一個觸發(fā)事件到來時苟径,Runloop 被喚醒,App 中的代碼會執(zhí)行一些操作躬审,比如創(chuàng)建和調整視圖層級
設置 UIView 的 frame、修改 CALayer 的透明度蟆盐、為視圖添加一些動畫承边;這些操作最終會被 CALayer 捕獲,并通過 CATransaction 提交到一個中間狀態(tài)去(CATransaction 的文檔中有提到這寫內容石挂,但并不完整)博助。當上面的所有操作結束后,Runloop 即將進入休眠或退出時痹愚,關注該事件的 Observer 都會得到通知富岳,這時 CA 注冊的那個 Observer 就會在回調中把所有的中間狀態(tài)合并提交到 GPU 去顯示;如果此處有動畫拯腮,CA 會通過 DisplayLink 等機制多次觸發(fā)相關流程窖式。
ASDK 在此處模擬了 CoreAnimation 的這個機制,所有針對 ASNode 的修改和提交动壤,總有些任務必須放到主線程中去執(zhí)行的萝喘。當出現這種任務的時候,ASNode 會把任務用 ASASyncTransaction(Group)封裝并提交到一個全新容器中去琼懊。ASDK 也在 Runloop 中注冊了一個Observer阁簸,監(jiān)聽的事件和CA一樣,但是優(yōu)先級比 CA 要低哼丈。在 Runloop 進入休眠前启妹,CA 處理完事件后,ASDK 就會執(zhí)行該 loop 內提交的所有任務醉旦。具體代碼見ASAsyncTransactionGroup饶米。
通過這種機制,ASDK 可以在合適的機會把同步车胡、異步的操作同步到主線程中去咙崎,并且能獲得不錯的性能。

  1. 其他
    ASDK 中還封裝了許多高級的功能吨拍,比如滑動列表的預加載褪猛、v2.0 添加新的布局模式等。
    ASDK 是一個很龐大的庫羹饰,它本身并不推薦你將整個 App 全部改為 ASDK 驅動伊滋,把最需要提升交互性能的地方用 ASDK 進行優(yōu)化就足夠了碳却。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市笑旺,隨后出現的幾起案子昼浦,更是在濱河造成了極大的恐慌,老刑警劉巖筒主,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件关噪,死亡現場離奇詭異,居然都是意外死亡乌妙,警方通過查閱死者的電腦和手機使兔,發(fā)現死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藤韵,“玉大人虐沥,你說我怎么就攤上這事昭伸⊙嗯迹” “怎么了镊掖?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵姑裂,是天一觀的道長弦聂。 經常有香客問我锌奴,道長椿每,這世上最難降的妖魔是什么坞生? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任然低,我火速辦了婚禮秋秤,結果婚禮上,老公的妹妹穿的比我還像新娘脚翘。我一直安慰自己灼卢,他們只是感情好,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布来农。 她就那樣靜靜地躺著鞋真,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沃于。 梳的紋絲不亂的頭發(fā)上涩咖,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機與錄音繁莹,去河邊找鬼檩互。 笑死,一個胖子當著我的面吹牛咨演,可吹牛的內容都是我干的闸昨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼饵较!你這毒婦竟也來了拍嵌?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤循诉,失蹤者是張志新(化名)和其女友劉穎横辆,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體茄猫,經...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡狈蚤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了划纽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脆侮。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖阿浓,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蹋绽,我是刑警寧澤芭毙,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站卸耘,受9級特大地震影響退敦,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蚣抗,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一侈百、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翰铡,春花似錦钝域、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至迷捧,卻和暖如春织咧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背漠秋。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工笙蒙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庆锦。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓捅位,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绿渣,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內容