iOS原理-renderLoop

字节的面试中,问了一道renderLoop的问题。我当时一脸懵逼😳,然后又问了UIView的渲染过程。当时没有回答好,准备好好总结一下。

Explore UI animation hitches and the render loop

卡顿(hitch)是什么?

A hitch is any time a frame appears on screen later than expected.
任何时候屏幕上出现晚于预计的帧都属于卡顿。

the Render loop

The Render Loop is a continuous process by which touch events are handed to an app, and then changes to the UI are sent to the operating system where the frame is finalized.It’s a loop, and it happens at the device’s refresh rate.

渲染循环是一个连续性的过程。通过触碰事件传送给app,然后转化到用户界面,向操作系统传送。最终呈现给用户,这就是循环,随着设备的刷新率发生。

the Render loop

整个渲染循环由五个阶段组成:

  1. 事件阶段(Event)
  2. 提交阶段(Commit)
  3. 渲染准备(Render prepare)
  4. 渲染执行(Render execute)
  5. 展示阶段(Display)

the Render loop 阶段

事件阶段(Event)

在这个阶段,App处理触碰事件或者Timer等其他事件,决定用户界面是否需要变化。

提交阶段(Commit)

在提交阶段,app向渲染服务器提交渲染命令。

渲染准备(Render prepare)

在下一个VSYNC中,渲染服务器处理命令,在渲染准备阶段,为在GPU上绘制做好准备。

渲染执行(Render execute)

在渲染执行阶段,GPU将用户界面的最后图像绘制出来。

展示阶段(Display)

在下一个VSYNC,这一帧将会呈现给用户。

一个例子展示整个渲染循环的过程。

布局是常见的性能问题,因为你的APP只有几毫秒来完成这项工作。

每个阶段都有截止时间,截止时间就是下个VSync信号到来的时间。

卡顿的类型(the type hitchs)

1.提交卡顿(commit hitch)
2.渲染卡顿(render hitch)

the type hitchs

提交卡顿

提交卡顿发生在APP的处理中。提交卡顿就是app花费过长时间来处理或提交事件。

commit hitch look like

渲染卡顿

渲染卡顿发生在渲染服务器中。这种现象发生在渲染服务器无法按时准备或者执行图层树时出现。
render hitch look like

测量卡顿时间 (measuring hitch time)

为什么不用总的卡顿时间?

苹果给出的测量卡顿的新指标
卡顿时间比(Htich time ratio)

the type hitchs

提交阶段的卡顿

提交事务

一次提交阶段有可以分成四个阶段:

布局阶段(layout)
显示阶段(display)
筹备阶段(prepare)
提交阶段(commit)

commit phase

布局阶段

layoutSubviews将会调用所有需要布局的视图

布局阶段

显示阶段

drawRect将会调用所有需要显示的视图

显示阶段

筹备阶段

如果有必要的话,图片将被解压
筹备阶段

提交阶段

提交阶段

使用instrement发现卡顿

结合自定义UI-手势密码组件进行实践。

建议

commit phase

commit phase

自己总结

渲染阶段的卡顿

渲染阶段

commit phase

commit phase
离屏通道是指图形处理器必须先在其他地方渲染一个图层然后再将其复制过来。

渲染通道使用太多,就会导致卡顿。

commit phase
有四种主要类型的离屏通道可以优化:

阴影
蒙板
圆角矩形
视觉效果

使用instrement发现卡顿

结合项目消息中心组件进行实践

建议

自己总结

参考资料

Explore UI animation hitches and the render loop

Find and fix hitches in the commit phase

Demystify and eliminate hitches in the render phase

iOS性能优化-卡顿检测和优化

*易的面试中的,面试官问了我一个如何检测页面卡顿的问题。当时没有回答好,所以来总结一下。

问题

1.如何检测iOS页面卡顿。
2.检查到卡顿的时候,需要将所有线程的堆栈信息,CPU,内存信息写入本地日志文件。

页面卡顿的原因

导致卡顿问题的几种原因:

  • 复杂UI,图文混排的绘制量过大;
  • 在主线程上做网络同步请求;
  • 在主线程做大量的IO操作;
  • 运算量过大,CPU持续高占用;
  • 死锁和主子线程抢锁。

卡顿的检查方案

通过监控主线程的RunLoop的状态来判断是否出现卡顿。将创建好的观察者 runLoopObserver 添加到主线程 RunLoop 的 common 模式下观察。然后,创建一个持续的子线程专门用来监控主线程的 RunLoop 状态。一旦发现进入睡眠前的 kCFRunLoopBeforeSources 状态,或者唤醒后的状态 kCFRunLoopAfterWaiting,在设置的时间阈值内一直没有变化,即可判定为卡顿。

我自己实践的代码

参考资料

13 | 如何利用 RunLoop 原理去监控卡顿?

Matrix-iOS 卡顿监控

微信iOS卡顿监控系统

iOS实时卡顿检测-RunLoop(附实例)

深入理解RunLoop

HTTPS建立连接过程

面试的时候只能说出个大概,一些细节都很模糊,所以就总结一下。

HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)是以安全为目标的 HTTP 协议,在 HTTP 的基础上通过传输加密和身份认证的方式保证了传输过程的安全性。其工作流程如下:

① 客户端发起一个 HTTPS 请求,并连接到服务器的 443 端口,发送的信息主要包括自身所支持的算法列表和密钥长度等;

② 服务端将自身所支持的所有加密算法与客户端的算法列表进行对比并选择一种支持的加密算法,然后将它和其它密钥组件一同发送给客户端。

③ 服务器向客户端发送一个包含数字证书的报文,该数字证书中包含证书的颁发机构、过期时间、服务端的公钥等信息。

④ 最后服务端发送一个完成报文通知客户端 SSL 的第一阶段已经协商完成。

⑤ SSL 第一次协商完成后,客户端发送一个回应报文,报文中包含一个客户端生成的随机密码串,称为 pre_master_secre,并且该报文是经过证书中的公钥加密过的。

⑥ 紧接着客户端会发送一个报文提示服务端在此之后的报文是采用pre_master_secre 加密的。

⑦ 客户端向服务端发送一个 finish 报文,这次握手中包含第一次握手至今所有报文的整体校验值,最终协商是否完成取决于服务端能否成功解密。

⑧ 服务端同样发送与第 ⑥ 步中相同作用的报文,已让客户端进行确认,最后发送 finish 报文告诉客户端自己能够正确解密报文。

当服务端和客户端的 finish 报文交换完成之后,SSL 连接就算建立完成了,之后就进行和 HTTP 相同的通信过程,唯一不同的是在 HTTP 通信过程中并不是采用明文传输,而是采用对称加密的方式,其中对称密钥已经在 SSL 的建立过程中协商好了。

参考资料