浅谈iOS Rendering 技术框架
*⚠️ iOS 渲染相关的层级划分大概如下:
UIKit -> CoreAnimation -> OpenGL ES = CoreGraphics -> Graphics Hardware (GPU)
UIKit
我们日常开发中使用的用户交互组件都来自于 UIKit Framework,我们通过设置 UIKit 组件的 Layout 以及 BackgroundColor 等属性来完成日常的界面绘画工作
CoreAnimation
Core Animation 本质上可以理解为是一个复合引擎,旨在尽可能快的组合屏幕上不同的显示内容。这些显示内容被分解成独立的图层,即 CALayer,CALayer 才是你所能在屏幕上看见的一切的基础,我们称之为图层树
OpenGL ES
OpenGL ES 简称 GLES,即 OpenGL for Embedded Systems,是 OpenGL 的子集,通常面向图形硬件加速处理单元(GPU)渲染 2D 和 3D 计算机图形
Core Graphics
Core Graphics Framework 基于 Quartz 高级绘图引擎。它提供了具有无与伦比的输出保真度的低级别轻量级 2D 渲染。您可以使用此框架来处理基于路径的绘图,转换,颜色管理,离屏渲染,图案,渐变和阴影,图像数据管理,图像创建和图像遮罩以及 PDF 文档创建,显示和分析
CPU 资源消耗原因和解决方案
- 对象创建:对象的创建会分配内存、调整属性、甚至还有读取文件等操作,比较消耗 CPU 资源。例如:通过 Storyboard 创建视图对象时,其资源消耗会比直接通过代码创建对象要大非常多, CALayer 比 UIView 要轻量许多,那么不需要响应触摸事件的控件,用 CALayer 显示会更加合适
- 对象调整:调整视图层次、添加和移除视图,UIView 的属性进行调整时,消耗的资源要远大于一般的属性。对此你在应用中,应该尽量减少不必要的属性修改
- 对象销毁:对象的销毁虽然消耗资源不多,但累积起来也是不容忽视的
- 布局计算:Autolayout 是苹果本身提倡的技术,在大部分情况下也能很好的提升开发效率,但是 Autolayout 对于复杂视图来说常常会产生严重的性能问题。频繁的,多次的修改布局会很消耗资源,使用ComponentKit、AsyncDisplayKit等框架
- 文本计算,渲染:常见的文本控件 (UILabel、UITextView 等),其排版和绘制都是在主线程进行的,当显示大量文本时,CPU 的压力会非常大,当然很少会出现这种现象,如果要解决这种现象,用CoreText,占用内存较少,可以缓存下来以备稍后多次渲染
- 图片的解码,图像的绘制:在后台线程先把图片绘制到 CGBitmapContext 中,然后从 Bitmap 直接创建图片。图像的绘制通常是指用那些以 CG 开头的方法把图像绘制到画布中,然后从画布创建图片并显示这样一个过程。这个最常见的地方就是 [UIView drawRect:] 里面了。由于 CoreGraphic 方法通常都是线程安全的,所以图像的绘制可以很容易的放到后台线程进行
GPU 资源消耗原因和解决方案
- 纹理的渲染:所有的 Bitmap,包括图片、文本、栅格化的内容,最终都要由内存提交到显存,绑定为 GPU Texture。不论是提交到显存的过程,还是 GPU 调整和渲染 Texture 的过程,都要消耗不少 GPU 资源。
- 视图的混合:如果视图结构过于复杂,混合的过程也会消耗很多 GPU 资源。为了减轻这种情况的 GPU 消耗,应用应当尽量减少视图数量和层次,并在不透明的视图里标明 opaque 属性以避免无用的 Alpha 通道合成
- 图形的生成:CALayer 的 border、圆角、阴影、遮罩(mask),CASharpLayer 的矢量图形显示,通常会触发离屏渲染(offscreen rendering),而离屏渲染通常发生在 GPU 中。
只有找到消耗的原因和对应的过程,才能针对性的去优化。圆角l为啥会造成资源消耗,消耗的又是什么资源?又怎么去优化?
网友评论