iOS 開發必定要嘗試的 Texture(ASDK)

原文連接 - iOS 開發必定要嘗試的 Texture(ASDK)(排版正常, 包含視頻)

前言

本篇所涉及的性能問題我都將根據滑動的流暢性來評判, 包括掉幀狀況和一些實際體驗html

ASDK 已經更名爲 Texture, 我習慣稱做 ASDKios

編譯環境: MacOS 10.13.3, Xcode 9.2git

參與測試機型: iPhone 6 10.3.3, iPhone 7 11.2.1, iPhone X 11.2.5, 默認 iPhone 6github

TableView / TableNode 包含的 TableViewCell / CellNode: 默認複雜程度通常, 包含 1~2 張圖片和 2~4 條文本展現, 圖片有圓角segmentfault

列表滑動卡頓的緣由及優化

大牛們把緣由都說的很清楚了, 致使的結果就是 16ms 不足以渲染一幀, 產生掉幀卡頓緩存

下面是嘗試過的一些優化:安全

圓角

  • 異步裁剪圖片: 經過 UIGraphics 對圖片進行裁剪, 可能形成內存暴漲

行高緩存

老生長談了, 除 UITableView-FDTemplateLayoutCell 以外, QMUI 中也有提供一套緩存行高方案性能優化

數據預加工

具體是在 JSON 轉 Model 後把文本轉爲富文本, 處理一些弱邏輯等, 以後賦值就能夠直接展現了網絡

咳咳, 這個感受不到什麼效果併發

圖形預加工

例如處理圖片遮罩或固定的圖標, 通常是直接使用多層視圖實現

我曾嘗試把三張小圖繪製到一張大圖上再進行展現, 因而乎, 異步複用問題除外, 內存炸了, 最終仍是老老實實用多個視圖實現

爲何要使用 ASDK

圖形異步渲染

一般咱們認爲 UIKit 是不能渲染於非主線程的, 一旦你這麼作, 就可能會致使崩潰, 沒法正常顯示等問題, 而 ASDK 爲何能夠呢, 由於 ASDisplayNode 是線程安全的, Node 建立時, 不會當即在其內部新建 UIView 和 CALayer, 直到主線程第一次訪問時纔會生成對應的對象, 除此以外, 還經過圖層預合成和基於 Runloop 的異步併發, 使其擁有更好的性能 ASAsyncTransactionGroup

這個特色帶來的相關實際體驗就是: 安心的進行異步繪圖, 如圓角裁剪, 增長遮罩等, 這在 UIKit 中是足以毀滅人生的, 內存暴漲, 異步複用, 性能極差

不太低性能設備下仍是會出現明顯空白

視頻連接

預加載數據和對象

首先來一張 Gif 體驗一下, 實際上使用 ASDK 開發完成後對比也是如此, 有種網速變快了的錯覺

ASDK 中的 ASRangeController, ASTableView, ASCollectionView 相對於 UIKit 原生控件的特色是可用於監控視圖的可見區域, 維護工做區域, 在合適的時機觸發網絡請求以及繪製, 單元格的異步佈局

2018-01-29 11.21.04

這裏推薦閱讀: 預加載與智能預加載(iOS)

異於原生控件的複用機制

單一的 Cell

意思是某個 List 展現的樣式只有一種, TableView 只須要註冊一個 Cell

這種狀況下, 若是常規的一些優化得當, 滾動的流暢性仍是能夠接受的(與 ASDK 差距微小, 但仍然肉眼可分辨)

此時的差距主要體如今列表某項數據第一次展現, 以及 TableView 在分頁加載時產生的等待較長, 固然, 這兩點也是能夠繼續優化和解決的

相反的, 也就是來回滑動已經展現過的數據, 二者的差距就很是小了, 大概是 59.7 - 59.9 和 59.9 的區別 (我瞎扯的)

綜上, 優化得當的狀況下, 單一的 Cell 狀況下 UIKit 與 ASDK 的差距不明顯

視頻連接

多種 Cell

表示某 List 中有多種不一樣的樣式, TableView 必需要經過註冊 N 個 Cell 來實現

這種狀況下, 假設有 5 種 Cell, 屏幕可同時展現 6 條 Cell, 此時若第一屏幕恰好展現的就包含所有 5 種 Cell , 那麼後續的滑動狀況將與單一的 Cell表現一致, 若第一屏幕展現的內容只包含一種, 其餘 4 種沒有在屏幕上出現過, 那麼當某一種首次出如今屏幕上時, 便會出現明顯的卡頓; 我嘗試過解決這個問題, 提早建立全部的 Cell 實例對象, 緩存和複用相同的子視圖, 異步預繪製爲一張圖片並緩存(坑), 都收效漸微

因 ASDK 支持預渲染, 與處理單種 Cell 沒有區別, 依舊 59.9

複用的差異

TableView 的複用機制我是既愛又恨的, 方便之處在於直接與數據綁定後, 能夠方便的更新和修改, 只需保證 setModel 簡潔就 OK, 只是當業務綁定較多時就比較麻煩了

下面重點說說 TableNode, TableNode 的複用機制就是沒有複用, 只有緩存, 每一個 CellNode 都是全新的, 所以會有一些特殊的地方:

CellNode 與數據源沒有綁定關係: 建立後就算把數據源刪除, TableNode 依然能夠正常展現

數據直接決定要建立一個怎樣的 CellNode: 這一點很重要, TableViewCell 的展現大體爲: 添加空假數據子視圖 -> 數據填充 -> 刷新, 涉及佈局或圖文時會更復雜
CellNode 只有一步: 添加真數據的子視圖; 所以能夠直接根據業務邏輯對控件和佈局作出處理, 而不用一次或屢次刷新

Demo: 此處需求爲每組一個大圖 + N個小圖, 每組 3 或 5 個

解決思路: TableView 的方式是建立 5 個, 根據數量顯隱下面兩個, 或者兩種 Cell, 把 3 和 5 的狀況分別對應, 除此以外, 最重要的是: 祈禱數據正常, 每組數據個數僅爲 3 或 5

此時若使用 TableNode 就靈活多了, 能夠根據須要(數據個數), 加入須要的子視圖, 個人思路是把頂部的大圖固定, 剩下的兩個爲一行進行添加, 就算總數爲偶數也是沒有任何額外消耗的, 具體參見 ASDKDemo

視頻連接

Flex 佈局

值得學習的理由

ASDK 使用的是 Flex 佈局, 且面向對象

偷一張圖

具體對比: iOS 上的 FlexBox 佈局

簡單來講, 缺點只有一個, 就是學習曲線相對 Frame AutoLayout 更陡峭, 而優勢是 性能與 Frame 至關, 上手後比 AutoLayout 還簡單, 若是你已經開始嘗試, 請堅持下去

不一樣的方式和思想

AutoLayout

使用 AutoLayout 時我內心想的無外乎:

  • 我要把你放在左上角: Left Top
  • 把你放在它右邊: LeftTo(它)
  • 放中間: Center
  • 至少/至多離它多遠: less / greater

缺點是視圖之間的依賴性太強, 可讀性維護性較差(更差的是 Frame), 例如排列數個距離不等控件, 就會很厭煩, 而後 cv 重複代碼; 處理多個多行文本垂直排列時很噁心, 想要處理好最終須要去計算文字行高, 外加入自定行間距; ...

Flex

例如 Demo 中的
<img src="https://img.didee.cn/imgs/201...; width="300"/>

我作的事情是:

  • 聲明大圖的比例: Ratio(9.0/16.0); 那麼這個聲明存儲爲 postImageRatioSpec
  • 聲明大標題的內邊距: Inset(8, 8, 8, 8); titleInsetSpec
  • 聲明 titleInsetSpec 的位置是垂直方向下的最尾部; titleRelativeSpec
  • 聲明 titleRelativeSpec 是覆蓋到 postImageRatioSpec 上: titleOverlaySpec

此時大圖和文字佈局完成

接下來是用戶欄:

  • 聲明用戶頭像和名稱水平排列, 水平方向從左也就是從頭部開始, 距離 4, 對齊方式爲居中, 此時的居中爲垂直方向; leftStackSpec
  • 同理, 聲明兩個圖標爲水平, 尾部起始, 距離4, 居中; rightStackSpec
  • 接下來, 聲明 leftStackSpecrightStackSpec 水平排列, 等間距排列填充(實際是爲 left 和 rightStack 進行填充), 距離 8, 對齊方式填充(無實際做用, 因爲子視圖同爲 Stack 且都是水平方向); userStackSpec

最後:

  • 聲明 titleOverlaySpecuserStackSpec 垂直排列, 自上而下, 對齊方式填充(同理於userStackSpec, 此處影響的是 userStackSpec); videoStackSpec
  • 聲明 videoStackSpec 的內邊距: Inset(16, 16, 0, 16); videoInsetSpec

特別注意 userStackSpecvideoStackSpec, StackSpec 多層疊加後, 父子間是存在影響的, 我在使用中也感受比較奇怪, 具體須要自行嘗試體會..

具體實現代碼: VideoCellNode.m , UserNode.m

相關連接 (不分前後)

文章

iOS性能優化探討

AsyncDisplayKit 系列教程 —— 爲何要使用 AsyncDisplayKit

新大陸:AsyncDisplayKit

iOS 保持界面流暢的技巧

Texture-Resources (EN 推薦)

Getting-Started 入門教程之一

Texture 佈局篇

視頻

AsyncDisplayKit State of the Code (WWDC 2016)

Demo

包含無限滾動和不定子視圖的 Demo ASDKDemo

官方示例 Texture Examples

線上項目 AppStore 耐飛視頻

相關文章
相關標籤/搜索