美文网首页
UI卡顿掉帧原因和滑动优化方案

UI卡顿掉帧原因和滑动优化方案

作者: Queen_BJ | 来源:发表于2020-09-04 17:34 被阅读0次

一、UI卡顿掉帧原因

iOS设备的硬件时钟会发出Vsync(垂直同步信号),然后App的CPU会去计算屏幕要显示的内容,之后将计算好的内容提交到GPU去渲染。随后,GPU将渲染结果提交到帧缓冲区,视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示。
也就是说,一帧的显示是由CPU和GPU共同决定的。
一般来说,页面滑动流畅是60fps,也就是1s有60帧更新,即每隔16.7ms就要产生一帧画面,而如果CPU和GPU加起来的处理时间超过了16.7ms,就会造成掉帧甚至卡顿

CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。

二、 滑动优化方案

CPU:把以下操作放在子线程中

1.预排版(布局计算、文本计算、缓存高度等等)
2.预渲染(文本等异步绘制,图片解码等)

  • 对象创建
    复杂界面不要用xib,多用懒加载
  • 文本渲染
    常见的文本控件其排版和绘制都是在主线程进行的,当显示大量文本时,CPU的压力会非常大。对此解决方案只有一个,那就是自定义文本控件,用TextKit或最底层的CoreText对文本异步绘制。CoreText对象创建后可直接获取文本的宽高等信息,避免了多次计算(调整UILabel大小时计算一遍、UILabel绘制时内部再计算一遍)。CoreText对象占用内存较少,可以缓存下来以备稍后多次渲染。
  • 文本计算
    如果一个界面中包含大量文本,文本的宽高计算会占用很大一部分资源,并且不可避免。可以参考一下UILabel内部的实现方式:
//计算文本高度
[NSAttributeString boundingRectWithSize: options: context: ];
//绘制文本
[NSAttributeString drawWithRect: options: context: ];

尽管这两个方法性能不错,但仍需放在后台线程以避免阻塞主线程。
如果用CoreText绘制文本,就可以先生成CoreText排版对象,然后自己计算。并且CoreText还能够保留供稍后绘制使用。

  • 图片的解码
    当使用UIImage或CGImageSource的那几个方法创建图片时,图片数据并不会立刻解码。图片设置到UIImageView或者CALayer.contents中去,并且CALayer被提交到GPU前,CGImage中的数据才会得到解码。这一步发生在主线程并且不可避免。
    如果想要绕开这个机制,常见的做法是在后台线程先把图片绘制到CGBitmapContext中,然后从Bitmap中直接创建图片。目前常见的网络图片库都自带这个功能。
GPU : 纹理渲染,视图混合
  • 纹理的渲染
    所有的Bitmap,包括图片、文本、栅格化的内容,最终都要有内存提交到缓存,绑定为GPU纹理。当在较短时间显示大量图片时(比如tableview存在很多图片并且快速滑动时),CPU占用率很低,GPU占用非常高,界面仍会掉帧。避免这种情况的方法只能是只能尽量减少在短时间内显示图片数量,尽可能将多张图片合成一张进行显示。
    多张图合成一张

  • 图形的生成
    CALayer的border、圆角、阴影、遮罩(mask)CAShapLayer的矢量图形显示,通常会触发离屏渲染(offscreen rendering),而离屏渲染通常发生在GPU中。当一个列表视图中出现大量圆角的CALayer并且快速滑动时,可以观察到GPU资源已占满而CPU资源消耗很少,这时界面帧数会降到很低。为了避免这种情况可以尝试开启CALayer.shouldRasterize属性,但这会把原本离屏渲染的操作转嫁到CPU上去。对于只需要圆角的某些场合,也可以用一张已经绘制好的圆角图片覆盖到原本视图上;最彻底的解决办法就是把需要显示的圆形在后台线程绘制为图片,避免使用圆角、阴影、遮罩等属性

  • 视图的混合
    多个视图(或者说CALayer)重叠在一起显示时,GPU会首先把它们混合在一起。如果视图结果过于复杂,混合的过程也会消耗很多GPU资源。为了减轻这种情况的GPU消耗,应用应当尽量减少视图数量和层次,并在不透明的的视图里标明opaque属性以避免无用的alpha通道合成。

一般遇到性能问题时,考虑以下问题:

是否受到CPU或者GPU的限制?
是否有不必要的CPU渲染?
是否有太多的离屏渲染操作?
是否有太多的图层混合操作?
是否有奇怪的图片格式或者尺寸?
是否涉及到昂贵的view或者效果?
view的层次结构是否合理?

可参考文章一
可参考文章二

相关文章

网友评论

      本文标题:UI卡顿掉帧原因和滑动优化方案

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