为了账号安全,请及时绑定邮箱和手机立即绑定

关于UI事件传递,图像显示,性能优化,离屏渲染

标签:
iOS
  • UIView与CALayer

  • 事件传递与视图响应链

  • 图像显示原理

  • UI卡顿掉帧原因

  • 滑动优化方案

  • UI绘制原理

  • 离屏渲染

一、UIView与CALayer

https://img3.sycdn.imooc.com/5e9d620700015b2f12000330.jpg  image

<单一职责原则>
UIView为CALayer提供内容,以及负责处理触摸等事件,参与响应链
CALayer负责显示内容contents

二、事件传递与视图响应链 :

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event; - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; 复制代码

   https://img1.sycdn.imooc.com/5e9d62070001ed0412000668.jpg  image     https://img3.sycdn.imooc.com/5e9d62070001879211440922.jpg  image

如果事件一直传递到UIAppliction还是没处理,那就会忽略掉

三、图像显示原理

https://img1.sycdn.imooc.com/5e9d620700011bbe12000479.jpg  image

1.CPU:输出位图
2.GPU :图层渲染,纹理合成
3.把结果放到帧缓冲区(frame buffer)中
4.再由视频控制器根据vsync信号在指定时间之前去提取帧缓冲区的屏幕显示内容
5.显示到屏幕上

 image


CPU工作
1.Layout: UI布局,文本计算
2.Display: 绘制
3.Prepare: 图片解码
4.Commit:提交位图



GPU渲染管线(OpenGL)
顶点着色,图元装配,光栅化,片段着色,片段处理


四、UI卡顿掉帧原因

https://img2.sycdn.imooc.com/5e9d62070001167e12000453.jpg  image

iOS设备的硬件时钟会发出Vsync(垂直同步信号),然后App的CPU会去计算屏幕要显示的内容,之后将计算好的内容提交到GPU去渲染。随后,GPU将渲染结果提交到帧缓冲区,等到下一个VSync到来时将缓冲区的帧显示到屏幕上。也就是说,一帧的显示是由CPU和GPU共同决定的。
一般来说,页面滑动流畅是60fps,也就是1s有60帧更新,即每隔16.7ms就要产生一帧画面,而如果CPU和GPU加起来的处理时间超过了16.7ms,就会造成掉帧甚至卡顿。

五、滑动优化方案
CPU:把以下操作放在子线程中
1.对象创建、调整、销毁
2.预排版(布局计算、文本计算、缓存高度等等)
3.预渲染(文本等异步绘制,图片解码等)

GPU:
纹理渲染,视图混合

一般遇到性能问题时,考虑以下问题:
是否受到CPU或者GPU的限制?
是否有不必要的CPU渲染?
是否有太多的离屏渲染操作?
是否有太多的图层混合操作?
是否有奇怪的图片格式或者尺寸?
是否涉及到昂贵的view或者效果?
view的层次结构是否合理?

六、UI绘制原理

https://img1.sycdn.imooc.com/5e9d620800017c8c12000718.jpg  image     https://img3.sycdn.imooc.com/5e9d6208000184e812000694.jpg  image


异步绘制:
[self.layer.delegate displayLayer: ]
代理负责生成对应的bitmap
设置该bitmap作为该layer.contents属性的值


https://img4.sycdn.imooc.com/5e9d62080001ade612000582.jpg  image

七、离屏渲染

On-Screen Rendering:当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行
Off-Screen Rendering:离屏渲染,分为CPU离屏渲染和GPU离屏渲染两种形式。GPU离屏渲染指的是GPU在当前屏幕缓冲区外新开辟一个缓冲区进行渲染操作
应当尽量避免的则是GPU离屏渲染


GPU离屏渲染何时会触发呢?
圆角(当和maskToBounds一起使用时)、图层蒙版、阴影,设置


layer.shouldRasterize = YES 复制代码



为什么要避免GPU离屏渲染?
GPU需要做额外的渲染操作。通常GPU在做渲染的时候是很快的,但是涉及到offscreen-render的时候情况就可能有些不同,因为需要额外开辟一个新的缓冲区进行渲染,然后绘制到当前屏幕的过程需要做onscreen跟offscreen上下文之间的切换,这个过程的消耗会比较昂贵,涉及到OpenGL的pipeline跟barrier,而且offscreen-render在每一帧都会涉及到,因此处理不当肯定会对性能产生一定的影响。另外由于离屏渲染会增加GPU的工作量,可能会导致CPU+GPU的处理时间超出16.7ms,导致掉帧卡顿。所以可以的话应尽量减少offscreen-render的图层


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
0
获赞与收藏
0

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消