https://zhuanlan.zhihu.com/p/72653360 ??關于iOS離屏渲染的深入研究 ? ???????????????? 寫的挺好?
https://mp.weixin.qq.com/s/6ckRnyAALbCsXfZu56kTDw ? 離屏渲染,渲染流程,較為詳細
cpu耗時操作
布局計算 —視圖層級過于復雜,視圖數(shù)量過多,當視圖呈現(xiàn)或者修改的時候,計算圖層,幀率被消耗一部分時間
Core Graphics繪制 - 如果對視圖實現(xiàn)了-drawRect:方法,或者CALayerDelegate的-drawLayer:inContext:方法,那么在繪制任何東西之前都會產(chǎn)生一個巨大的性能開銷。
解壓圖片 - iOS通常直到真正繪制的時候才去解碼圖片,,對于一個較大的圖片,都會占用一定的時間。
GPU 耗時操作
太多的幾何結(jié)構(gòu) : ? 圖片合并,透明度計算。
為什么離屏渲染會發(fā)生卡頓?主要包括兩方面內(nèi)容:
創(chuàng)建新的緩沖區(qū)。
上下文切換,離屏渲染的整個過程,需要多次切換上下文環(huán)境(CPU渲染和GPU切換),先是從當前屏幕(On-Screen)切換到離屏(Off-Screen);等到離屏渲染結(jié)束以后,將離屏緩沖區(qū)的渲染結(jié)果顯示到屏幕上又需要將上下文環(huán)境從離屏切換到當前屏幕。而上下文環(huán)境的切換是要付出很大代價的。
離屏渲染的優(yōu)化建議
使用ShadowPath指定layer陰影效果路徑。
使用異步進行l(wèi)ayer渲染(Facebook開源的異步繪制框架AsyncDisplayKit)。
設置layer的opaque值為YES,減少復雜圖層合成。
盡量使用不包含透明(alpha)通道的圖片資源。
盡量設置layer的大小值為整形值。
直接讓美工把圖片切成圓角進行顯示,這是效率最高的一種方案。
很多情況下用戶上傳圖片進行顯示,可以在客戶端處理圓角。
使用代碼手動生成圓角image設置到要顯示的View上,利用UIBezierPath(Core Graphics框架)畫出來圓角圖片。
合理使用光柵化 shouldRasterize:光柵化是把GPU的操作轉(zhuǎn)到CPU上,生成位圖緩存,直接讀取復用。
優(yōu)點:
CALayer會被光柵化為bitmap,shadows、cornerRadius等效果會被緩存。
缺點:
更新已經(jīng)光柵化的layer,會造成離屏渲染。
bitmap超過100ms沒有使用就會移除。
受系統(tǒng)限制,緩存的大小為 2.5X Screen Size。
shouldRasterize適合靜態(tài)頁面顯示,動態(tài)頁面會增加開銷。如果設置了shouldRasterize為YES,那也要記住設置rasterizationScale為contentsScale。
過大的圖片 - 如果視圖繪制超出GPU支持的2048x2048或者4096x4096尺寸的紋理,就必須要用CPU在圖層每次顯示之前對圖片預處理,同樣也會降低性能。
子線程預解碼(Decode),主線程直接渲染。因為當image沒有Decode,直接賦值給imageView會進行一個Decode操作。
優(yōu)化圖片大小,盡量不要動態(tài)縮放(contentMode)。
盡可能將多張圖片合成為一張進行顯示。
減少透明 view
使用透明view會引起blending,在iOS的圖形處理中,blending主要指的是混合像素顏色的計算。最直觀的例子就是,我們把兩個圖層疊加在一起,如果第一個圖層的透明的,則最終像素的顏色計算需要將第二個圖層也考慮進來。這一過程即為Blending。
會導致blending的原因:
UIView的alpha<1。
UIImageView的image含有alpha channel(即使UIImageView的alpha是1,但只要image含有透明通道,則仍會導致blending)。
為什么blending會導致性能的損失?
原因是很直觀的,如果一個圖層是不透明的,則系統(tǒng)直接顯示該圖層的顏色即可。而如果圖層是透明的,則會引起更多的計算,因為需要把另一個的圖層也包括進來,進行混合后的顏色計算。
opaque設置為YES,減少性能消耗,因為GPU將不會做任何合成,而是簡單從這個層拷貝。
超大圖導致的內(nèi)存暴增,carsh ,解決:
SDW 中 decodeImageWithImage這個方法用于對圖片進行解壓縮并且緩存起來。
解壓縮操作中,每一個像素點都會分配一個空間來存儲相關值,那么分辨率越高的圖片,就意味著更多數(shù)量的像素點,也就意味著需要分配更多的空間!所以對于高分辨率圖來說,如果緩存解壓縮之后的數(shù)據(jù),即使是幾M的圖片,也是有可能消耗上G的內(nèi)存!
解決:在需要下載高分辨率圖的地方,避免--緩存解壓縮后的數(shù)據(jù)操作,手動關閉SDWeb緩存方法。大圖加載后再手動打開
解碼操作:
一般我們使用的圖像是JPEG/PNG,這些圖像數(shù)據(jù)不是位圖,是經(jīng)過編碼壓縮后的數(shù)據(jù),需要將它解碼轉(zhuǎn)成位圖數(shù)據(jù),才能把位圖渲染到屏幕上。
用 UIImage 或 CGImageSource 的那幾個方法創(chuàng)建圖片時,圖片數(shù)據(jù)并不會立刻解碼。圖片設置到 UIImageView 或者 CALayer.contents 中去,并且 CALayer 被提交到 GPU 前,CGImage 中的數(shù)據(jù)才會得到解碼。這一步是發(fā)生在主線程的,并且不可避免。
iOS默認是在主線程解碼,所以SDWebImage將這個過程放到子線程了。同時因為位圖體積很大,所以磁盤緩存不會直接緩存位圖數(shù)據(jù),而是編碼壓縮后的PNG或JPG數(shù)據(jù)。
https://blog.ibireme.com/2015/11/02/ios_image_tips/ ? ? ?UIImage 加入緩存和 解碼過程中的一些小 知識點?
將 UIImage 保存到磁盤,用什么方式最好?
目前來說,保存 UIImage 有三種方式:1.直接用 NSKeyedArchiver 把 UIImage 序列化保存,2.用 UIImagePNGRepresentation() 先把圖片轉(zhuǎn)為 PNG 保存,3.用 UIImageJPEGRepresentation() 把圖片壓縮成 JPEG 保存。
實際上,NSKeyedArchiver 是調(diào)用了 UIImagePNGRepresentation 進行序列化的,用它來保存圖片是消耗最大的。
蘋果對 JPEG 有硬編碼和硬解碼,保存成 JPEG 會大大縮減編碼解碼時間,也能減小文件體積。
所以如果圖片不包含透明像素時,UIImageJPEGRepresentation(0.9) 是最佳的圖片保存方式,其次是 UIImagePNGRepresentation()。

離屏渲染,頁面卡頓常見問題以及解決:
iOS性能優(yōu)化之CPU、GPU的優(yōu)化(一) - 簡書
iOS 保持界面流暢的技巧 | Garan no dou? ? ?AsyncDisplayKit 框架學習
==================================圖片壓縮 和 大圖內(nèi)存崩潰原因 ?================================
“壓” 是指文件體積變小,但是像素數(shù)不變,長寬尺寸不變,那么質(zhì)量可能下降。 jpeg ?圖片不會模糊,但是圖片可能不能壓縮到指定大小 ,適用于原相機拍攝出來的照片
“縮” 是指文件的尺寸變小,也就是像素數(shù)減少,而長寬尺寸變小,文件體積同樣會減小。 png ? 可以壓縮到指定大小,但是可能會模糊 ,使用于帶有 透明通道,幾何圖等。
使用SDWebImage下載高分辨率圖,導致內(nèi)存暴增的解決辦法 - 簡書
iOS壓縮圖片的兩種方式 - 簡書? ?系統(tǒng)自帶壓縮圖片質(zhì)量 & 壓縮圖片大小,對圖片進行裁剪
iOS 圖片壓縮處理 - 簡書? 兩種壓縮方式詳解和對比。
========================= ?高清大圖壓縮和上傳 ================================
大文件分片上傳:大文件分片上傳 & 斷點續(xù)傳
將大圖分解成小片然后將他們單獨按需載入。在多個線程中為每個小塊同時調(diào)用 -drawLayer:inContext: 方法。
這就避免了阻塞用戶交互而且能夠利用多核心新片來更快地繪制。只有一個小塊的 CATiledLayer 是實現(xiàn)異步更新圖片視圖的簡單方法。