美文网首页
UIView的绘制原理及优化

UIView的绘制原理及优化

作者: 打碟的DJ | 来源:发表于2019-07-27 21:33 被阅读0次

UI卡顿&掉帧的原因

一般页面滑动的帧数在60fps以内时,页面才会流畅,也就是说每一秒内有60次的画面更新,相当于在每隔16.7ms产生一帧画面,在16.7ms内 CPUGPU 要完成一帧画面的绘制与渲染。

图片显示
  • 正常显示:

比如说 CPU 要在一定时间内完成视图的文本的布局、视图的绘制以及图片的解码等工作,最终将位图 (bitmap) 提交给 GPU ,然后 GPU 完成视图的渲染,最终在16.7ms内提交给视频控制器显示在屏幕上。

图片掉帧
  • 掉帧

如果说 CPU 在16.7ms内占用的时间过多,最终导致 GPU 在16.7ms以后才将图片渲染完提交给视频控制器,就会导致掉帧,UI界面的卡顿

UIView的绘制原理

UIView的绘制原理

当调用 UIView\color{red}{setNeedsDisplay} 方法时并不会立即绘制视图,它会先调用视图所对应的的 layer 的同名方法 \color{red}{setNeedsDisplay} 方法,相当于在当前视图上打上了个脏标记,然后在当前 runloop 将要结束时调用 CALyer\color{red}{display} 方法,最后才会进入绘制流程当中。
在调用 CALyer\color{red}{display} 方法时,首先会先判断是否响应 layer\color{red}{displayLayer} 代理方法,如果不响应则进入系统绘制流程,当响应时,则进入异步绘制入口。

系统绘制流程

系统绘制流程图
  • CALayer 会回先创建一个 backing storeCGContextRef) 的上下文,然后会在 drawRect 方法中会在上下文堆栈中拿到 backing store
  • 判断是否 CALayer 是否有代理
  • 如果没有代理,则调用系统的 \color{red}{drawInContext:} 方法
  • 如果有代理,则会调用 layer.delegate\color{red}{drawLayer:inContext:} 方法,该方法发生自系统内部,最后在合适的时机会调用 \color{red}{[UIView drawRect:]} 方法,该方法默认是什么都不做的
  • 最后都会将 backing store (位图)上传至GPU中,最后结束绘制

异步绘制

- [layer.delegate displayerLayer:]
  • 代理负责生成对应的bitmap
  • 设置该bitmap作为layer.contents属性的值
异步绘制时序图
  • 假如说在某个时间调用 \color{red}{setNeedsDisplay} 方法
  • 然后在当前 runloop 将要结束的时候,会由系统调用视图所对应的 \color{red}{CALyer display} 方法,如果我们的 delegate 方法实现了 \color{red}{displayerLayer} 方法,则由系统调用该方法
  • 然后会通过子线程的切换,在子线程中实现视图的绘制
  • 在子线程中创建位图的上下文(\color{red}{- CGBitmapContextCreate()}),然后做UI的绘制工作(\color{red}{CoreGraphic 的 API}),然后根据绘制的上下文生成一张 CGImage 图片(\color{red}{- CGBitmapContextCreateImage()}
  • 最后回到主队列中,将该 CGImage 图片设置为 CALayercontents

离屏渲染

  • 在屏渲染(On-Screen Rendering)

指的是 \color{red}{GPU} 的渲染操作是在用于当前屏幕显示的缓冲区中进行的

  • 离屏渲染(Off-Screen Rendering)

指的是 \color{red}{GPU} 在当前屏幕缓冲区以外开辟一个 \color{red}{新的缓冲区} 进行渲染操作

  • 离屏渲染何时触发

1、设置圆角(同时设置maskToBounds时才会触发)
2、设置视图的图层蒙版
3、设置阴影
4、设置光栅化

  • 为何要避免离屏渲染

离屏渲染会导致 GPU 增加额外的开销,会导致在CPU和GPU处理的视图的总时长增加,超过16.7ms,可能会导致视图的卡顿和掉帧

滑动优化方案

  • CPU:

1、对象的创建、调整、销毁
2、预排版(布局计算、文本计算等)
3、预渲染(文本的异步绘制、图片的编解码等)

  • GPU:

1、避免离屏渲染
2、避免视图混合(视图层级太多)

相关文章

网友评论

      本文标题:UIView的绘制原理及优化

      本文链接:https://www.haomeiwen.com/subject/yrjlrctx.html