美文网首页
iOS UI卡顿的原因及解决方案

iOS UI卡顿的原因及解决方案

作者: 孙掌门 | 来源:发表于2020-03-02 21:37 被阅读0次

    iOS UI卡顿的原因及解决方案

    CPU

    cpu 就是中央处理器,主要负责计算,对象创建和销毁,文本的排版,图片的格式转换,解码,图像的绘制(core graphics)

    GPU

    GPU 是图像处理器,主要负责纹理的渲染

    显示流程

    CPU计算->GPU(渲染)-> 帧缓存(前缓存和后缓存) -> 读取到视频控制器 -> 显示

    屏幕成像原理

    当屏幕发出垂直同步信号的时候(vsync),就代表要显示一帧了,当发出水平同步信号的时候(HSync),就代表要显示一行数据,一行一行的显示,直到显示一个屏幕

    卡顿产生的原因

    当我们需要显示数据的时候,首先需要 CPU 计算,当CPU计算好了之后,把数据提交给GPU渲染,当我们的屏幕发出 VSync 的时候,就代表要显示了,这时候就从缓存中拿出数据显示,当我们的GPU渲染事件太长的时候,比如渲染到一半的时候,这时候 VSync 信号过来了,而这时候并没有渲染完,而这个信号过来的时候又要显示出来,这个时候就出现了丢帧,这时候屏幕显示的还是上一帧,就形成了卡顿。而这一帧只能等下一次 VSync 信号过来才能显示

    离屏渲染

    On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染
    Off-Screen Rendering:离屏渲染,在当前屏幕以外新开辟一个缓冲区进行渲染

    离屏渲染耗性能原因:

    1. 需要创建新的缓冲区
    2. 离屏渲染整个过程,需要多次切换上下文,先是从当前屏幕切换到离屏,等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,有需要将离屏上下文环境切换到当前屏幕。

    触发离屏渲染:

    1. 光栅化:layer.shouldRasterize = YES;
    2. 遮罩:layer.mask
    3. 圆角:同时设置 layer.masksToBounds = YES ,layer.cornerRadius > 0两个条件都满足,可以使用 coreGraphics 来绘制裁剪圆角,或者 UI 直接提供圆角
    4. 阴影:layer.shadow,如果设置了 shadowPath 就不会产生离屏渲染。

    解决方案

    尽量减少 CPU GPU 资源消耗,按照1s钟60FPS的刷新来算,一秒相当于1000ms,大概每隔 16ms 就会有一次 VSync 信号

    CPU 优化

    1. 尽量使用轻量级的对象,减少 CPU 的计算,尽量用 CALayer 替代 UIView。
    2. 尽量不要太频繁的调整 UIView 的属性,比如 frame ,bounds等。
    3. 尽量做预处理,提前算好布局,然后最后再赋值,不要频繁设置,也不再在显示的时候再计算
    4. 少用 autolayout ,比 frame 更加耗性能。
    5. 图片和imageview的大小要保证大小一致,不要让它自己缩放
    6. 控制线程的数量,最大并发量,不要造太多的线程
    7. 尽量把耗时的操作放到子线程中(文本处理,尺寸计算)
    8. 图片的解码,绘制,放到子线程中。可以利用 CGContextRef ,图形上下文,进行解码

    GPU 优化

    1. 尽可能的减少视图的层级和数量。
    2. 尽量避免短时间内进行大量图片显示
    3. GPU 能处理最大纹理尺寸为 4096 X 4096,如果超过就会占用 cpu 资源进行处理。
    4. 减少透明的视图(alpha < 1),如果图片透明,就需要一定量的计算,不透明就设置 opaque 为 yes。比如重叠部分的计算,是需要计算的,如果不透明的话,就直接盖上去就可以了
    5. 尽量避免离屏渲染。

    相关文章

      网友评论

          本文标题:iOS UI卡顿的原因及解决方案

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