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

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

前言

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

ASDK 已經改名為 Texture, 我習慣稱作 ASDK

編譯環境: MacOS 10.13.3, Xcode 9.2

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

TableView / TableNode 包含的 TableViewCell / CellNode: 默認復雜程度一般, 包含 1~2 張圖片和 2~4 條文本展示, 圖片有圓角

列表滑動卡頓的原因及優化

大牛們把原因都說的很清楚了, 導致的結果就是 16ms 不足以渲染一幀, 產生掉幀卡頓

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

圓角

  • 使用一張圓角圖片覆蓋, 經典文章 Corner Rounding, HYBImageCliped 也是這么做的

  • 異步裁剪圖片: 通過 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 耐飛視頻

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391262.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391262.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391262.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

lisp語言是最好的語言_Lisp可能不是數據科學的最佳語言,但是我們仍然可以從中學到什么呢?...

lisp語言是最好的語言This article is in response to Emmet Boudreau’s article ‘Should We be Using Lisp for Data-Science’.本文是對 Emmet Boudreau的文章“我們應該將Lisp用于數據科學”的 回應 。 Below, unless otherwise stated, lisp refers to Common Lisp; in …

鏈接訪問后刷新顏色回到初始_如何使鏈接可訪問(提示:顏色不夠)

鏈接訪問后刷新顏色回到初始Link accessibility is one of the most important aspects of usability. However, designers often dont understand what it takes to make links accessible. Most frequently, they only distinguish links by color, which makes it hard for …

567

567 轉載于:https://www.cnblogs.com/Forever77/p/11519678.html

leetcode 403. 青蛙過河(dp)

一只青蛙想要過河。 假定河流被等分為若干個單元格&#xff0c;并且在每一個單元格內都有可能放有一塊石子&#xff08;也有可能沒有&#xff09;。 青蛙可以跳上石子&#xff0c;但是不可以跳入水中。 給你石子的位置列表 stones&#xff08;用單元格序號 升序 表示&#xff…

static、volatile、synchronize

原子性&#xff08;排他性&#xff09;&#xff1a;不論是多核還是單核&#xff0c;具有原子性的量&#xff0c;同一時刻只能有一個線程來對它進行操作&#xff01;可見性&#xff1a;多個線程對同一份數據操作&#xff0c;thread1改變了某個變量的值&#xff0c;要保證thread2…

tensorflow基本教程

轉載自 http://tensornews.cn/ 轉載于:https://www.cnblogs.com/Chris-01/p/11523316.html

1.10-linux三劍客之sed命令詳解及用法

內容:1.sed命令介紹2.語法格式,常用功能查詢 增加 替換 批量修改文件名第1章 sed是什么字符流編輯器 Stream Editor第2章 sed功能與版本處理出文本文件,日志,配置文件等增加,刪除,修改,查詢sed --versionsed -i 修改文件內容第3章 語法格式3.1 語法格式sed [選項] [sed指令…

python pca主成分_超越“經典” PCA:功能主成分分析(FPCA)應用于使用Python的時間序列...

python pca主成分FPCA is traditionally implemented with R but the “FDASRSF” package from J. Derek Tucker will achieve similar (and even greater) results in Python.FPCA傳統上是使用R實現的&#xff0c;但是J. Derek Tucker的“ FDASRSF ”軟件包將在Python中獲得相…

blender視圖縮放_如何使用主視圖類型縮放Elm視圖

blender視圖縮放A concept to help Elm Views scale as applications grow larger and more complicated.當應用程序變得更大和更復雜時&#xff0c;可幫助Elm Views擴展的概念。 In Elm, there are a lot of great ways to scale the Model, and update, but there is more c…

初探Golang(2)-常量和命名規范

1 命名規范 1.1 Go是一門區分大小寫的語言。 命名規則涉及變量、常量、全局函數、結構、接口、方法等的命名。 Go語言從語法層面進行了以下限定&#xff1a;任何需要對外暴露的名字必須以大寫字母開頭&#xff0c;不需要對外暴露的則應該以小寫字母開頭。 當命名&#xff08…

789

789 轉載于:https://www.cnblogs.com/Forever77/p/11524161.html

sql的split()函數

ALTER function [dbo].[StrToList_Test](Str varchar(max), fg NVARCHAR(200)) returns table table(value nvarchar(max) ) as begindeclare tempStr nvarchar(max),len INT LEN(fg); --去除前后分割符 while substring(Str,1,len)fg beginset Strsubstring(Str,len1,len(S…

大數據平臺構建_如何像產品一樣構建數據平臺

大數據平臺構建重點 (Top highlight)Over the past few years, many companies have embraced data platforms as an effective way to aggregate, handle, and utilize data at scale. Despite the data platform’s rising popularity, however, little literature exists on…

初探Golang(3)-數據類型

Go語言擁有兩大數據類型&#xff0c;基本數據類型和復合數據類型。 1. 數值類型 ##有符號整數 int8&#xff08;-128 -> 127&#xff09; int16&#xff08;-32768 -> 32767&#xff09; int32&#xff08;-2,147,483,648 -> 2,147,483,647&#xff09; int64&#x…

freecodecamp_freeCodeCamp的服務器到底發生了什么?

freecodecampUpdate at 17:00 California time: We have now fixed most of the problems. Were still working on a few known issues, but /learn is now fully operational.加利福尼亞時間17:00更新 &#xff1a;我們現在解決了大多數問題。 我們仍在處理一些已知問題&#…

為什么Linux下的環境變量要用大寫而不是小寫

境變量的名稱通常用大寫字母來定義。實際上用小寫字母來定義環境變量也不會報錯&#xff0c;只是習慣上都是用大寫字母來表示的。 首先說明一下&#xff0c;在Windows下是不區分大小寫的&#xff0c;所以在Windows下怎么寫都能獲取到值。 而Linux下不同&#xff0c;區分大小寫&…

python:連接Oracle數據庫后控制臺打印中文為??

打印查詢結果&#xff0c;中文顯示為了&#xff1f;&#xff1f;&#xff1f; [(72H FCR, 2.0), (?????, 8.0)] E:\Python35\Lib\site-packages中新增文件&#xff1a; sitecustomize.py import os os.environ[NLS_LANG] SIMPLIFIED CHINESE_CHINA.UTF8 轉載于:https://w…

時間序列預測 時間因果建模_時間序列建模以預測投資基金的回報

時間序列預測 時間因果建模Time series analysis, discussed ARIMA, auto ARIMA, auto correlation (ACF), partial auto correlation (PACF), stationarity and differencing.時間序列分析&#xff0c;討論了ARIMA&#xff0c;自動ARIMA&#xff0c;自動相關(ACF)&#xff0c;…

初探Golang(4)-map和流程控制語句

1.map map 是引用類型的&#xff0c;如果聲明沒有初始化值&#xff0c;默認是nil。空的切片是可以直接使用的&#xff0c;因為他有對應的底層數組,空的map不能直接使用。需要先make之后才能使用。 //1, 聲明map 默認值是nil var m1 map[key_data_type]value_data_type 聲明 …

網絡傳輸之TCP/IP協議族

我們現實網絡無處不在&#xff0c;我們被龐大的虛擬網絡包圍&#xff0c;但我們卻對它是怎樣把我們的信息傳遞并實現通信的&#xff0c;我們并沒有了解過&#xff0c;那么當我們在瀏覽器中出入一段地址&#xff0c;按下回車這背后都會發生什么&#xff1f; 比如說一般場景下&am…