阅读 669

《iOS之一起进大厂》系列-iOS如何监控界面卡顿掉帧,如何优化

学而时习之,不亦说乎

前面的话

大家好,我是杯子,写这个系列,一是为了学习和复习。二是为了更好阅读体验。看了很多类似面试题的博文或总结pdf.内容有两类 ,一类是很言简意赅的干货,很短,但是看了理解不了,记不住,死记硬背的话又不知道原理和逻辑。 一类是博文是写的很长很详细,看完后面了,忘了前面,最后也不知道重点在哪。其实大家面试的时候,不可能像平时看文章那样,能把每个细节都描述的清清楚楚,面试时主要能把关键点讲出来,并且能在进一步提问中,把这些点的原理串联起来,保持逻辑清晰。希望大家看到我写的这个系列能有这样的帮助,文章既不冗长,也不是简短不能理解简短答案。

PS: 下面用模仿面试的问答模式,把相关的问题和知识点串联起来。 这样可以提高阅读体验,还可以加深记忆。

在这里插入图片描述
在这里插入图片描述

开始面试

我正在会议室等待,忽然看到一个穿着格子衬衫,大腹便便的中年男子拿着简历向我走来, 我看着他头上快要绝顶的头发,心想这肯定是个iOS开发技术牛逼闪闪的老前辈。 还好看过杯子写《iOS之一起进大厂》系列,想想现在是满腹经纶,刚紧张到提到嗓子眼的心,又按下去了,淡定从容,一点都不虚好伐,就是这么自信淡定。

小伙子,看你简历上提到,对视图的性能优化有一些了解,你可不可以先说下 图像显示相关的原理

帅气逼人的面试官您好, iOS系统中 CPU、GPU、显示器是以下面图中方式协同工作的。CPU和GPU是通过总线链接起来的,CPU 计算好显示内容提交到 GPU,GPU 渲染完成后将渲染结果放入帧缓冲区,视频控制器会按照 VSync 信号逐行读取帧缓冲区的数据,经过数模转换传递给显示器显示。 下图就是图像显示的流程: 图像显示流程

关于CPU和GPU的分工又有以下内容:

  • CPU负责:
    • 对象创建和销毁
    • 对象属性调整
    • 布局计算、文本的计算
    • 排版、图片的格式转换和解码
    • 图像的绘制
  • GPU负责:
    • 纹理的渲染
    • 视图的混合
    • 图形的生成

既然了解图像显示的原理,那你知道IOS视图卡顿掉帧的原因吗?

卡顿掉帧
卡顿掉帧

标准情况下,页面滑动流畅是60FPs ,就是每一秒有60帧的画面刷新,每16.7ms(1/60秒)有一帧数据。上图两个VSync 之间的时间就是16.7ms。 如果CPU 和 GPU 加起来的处理时间超过了 16.7ms,就会造成掉帧甚至卡顿。当FPs 帧数低于30时,人的肉眼就能感觉到画面明显的卡顿。

面试官吹了下自己的头发帘,心想,小伙子不错,都回答到点子上了,那再聊的深一点,那你知道如何监控界面的卡顿吗

既然知道了造成卡顿的原因,监控卡顿的思路就有了。

  • 思路一:监控一秒钟内的帧数是否经常低于或远低于 60FPs。
  • 思路二:监控每一帧的时长是否超时。

思路一实现方法:用 CADisplayLinker 来计数

CADisplayLink可以以屏幕刷新的频率调用指定selector,iOS系统中正常的屏幕刷新率为60次/秒,只要在这个方法里面统计每秒这个方法执行的次数,通过次数/时间就可以得出当前屏幕的刷新率了。

思路二实现方法:通过子线程监测主线程的RunLoop,判断两个状态RunLoop的状态区域之间的耗时是否达到一定阈值。

开启子线程,实时计算这两个状态区域之间的耗时是否到达某个阀值,便能揪出这些性能杀手,假定连续6次超时50ms认为卡顿(当然也包含了单次超时300ms)

老面试官露出了满意的笑容,不过做戏做要做全套嘛,那你最后说说如何优化掉帧卡顿

图像显示的工作是由CPU和GPU协同完成的, 那么优化的方向和思路就是尽量减少他们的处理时长。

对CPU处理的优化:

  • 在子线程中进行对象的创建,调整和销毁,节省一部分CPU的时间
  • 在子线程中预排版(布局计算,文本计算),让主线程有更多的时间去响应用户的交互
  • 对文本等异步绘制,图片编解码等内容进行 预渲染、预排版

对GPU处理的优化

  • 尽量避免使用 CALayer 的 Border、corner、shadow、mask 等技术,这样能少触发离屏渲染
  • 尽可能将多张图片合成为一张进行显示,减轻视图层级

面试结束

小伙子回答的不错,明天接着面试其他内容。 天呐噜,明天还有。 (为了下一篇文章,强行做引子,哈哈)

总结

文中主要是针对了图像原理,卡顿掉帧的原因,优化方案。

  • 原理:CPU负责计算,GPU负责渲染,渲染结果放到帧缓冲区再到显示器上显示。
  • 原因:CPU加GPU的处理耗时超过1/60秒时,就出现了掉帧,甚至卡顿。
  • 监控:监控掉帧卡顿有两种思路,监控 时间内帧数 和RunLoop两状态间的耗时是否超过阈值。

其实对视图的优化还有很多方面,比如使用UIView的异步绘制,如何避免离屏渲染,在使用TableView 如何具体优化没有提到,这些需要另外的文章篇幅才能描述清楚。 不用全堆到一起。

坚持看到这里的同学,你们个个都是人才,我好喜欢。

求 点关注,加收藏,求分享

创作不易,决绝白嫖,大家好我是空杯子,文章每周持续更新,如果这个文章写得还不错,觉得「杯子」我有写的东西对你有点用的话 求点赞👍 求关注❤求分享

如果本篇博客有任何错误,请批评指教,不胜感激 !

在微信公众号中搜索 「 空杯子One 」 或扫描下面二维码 第一时间阅读和催更(比博客早一到两篇哟),还可以获取整理好的最全的iOS面试题、答案和iOS学习资料。 本文在GitHub github.com/schelling/i… 已经收录,那有一线大厂面试点思维导图,也整理了很多我的博客文档,欢迎Star和完善,大家面试可以参照考点复习,一起学而时习之,不亦说乎。

空杯子的微信公众号