本文主要介绍Heimdallr对卡死、卡顿异常的监控原理,并结合长时间的业务沉淀发现的问题进行不断迭代和优化,逐步实现全面、稳定、可靠的历程。
作者:字节跳动终端技术——白昆仑
前言
卡死、卡顿作为目前iOS App的重要性能指标,不仅影响着用户体验,更关系到用户留存、DAU等重要产品数据。本文主要介绍Heimdallr
对卡死、卡顿异常的监控原理,并结合长时间的业务沉淀发现的问题进行不断迭代和优化,逐步实现全面、稳定、可靠的历程。
一、什么是卡死/卡顿?
卡顿,顾名思义就是在使用过程中出现了一段时间的阻塞,使得用户在这一段时间内无法进行操作,屏幕上的内容也没有任何的变化。Heimdallr
在监控指标上,根据阻塞时间的长短进行了3个等级的划分。
1、流畅性与丢帧:动画、滑动列表不流畅,一般为十几至几十毫秒的级别
2、卡顿:短时间操作无反应,恢复后能继续使用,从几百毫秒至几秒
3、卡死:长时间无反应,直至被系统杀死,通过线上收集数据,最少为5s
可以看到,根据严重性由小至大可将卡顿问题划分为流畅性与丢帧、卡顿、卡死三个不同的等级。卡死的严重程度与Crash是相当的,甚至更为严重。因为卡死不仅仅造成了类似于崩溃的闪退,更使得用户被迫等待了相当长的一段时间,更加损害用户的体验。由于监控方案上的差异,本文主要面向的是后两者卡顿和卡死的监控。
二、卡死/卡顿的原因
iOS开发中,由于UIKit是非线程安全的,因此一切与UI相关的操作都必须放在主线程执行,系统会每16ms(1/60帧)将UI的变化重新绘制,渲染至屏幕上。如果UI刷新的间隔能小于16ms,那么用户是不会感到卡顿的。但是如果在主线程进行了一些耗时的操作,阻碍了UI的刷新,那么就会产生卡顿,甚至是卡死。主线程对于任务的处理是基于Runloop
机制,如下图所示。Runloop支持外部注册通知回调,提供了
1、RunloopEntry
2、RunloopBeforeTimers
3、RunloopBeforeSources
4、RunloopBeforeWaiting
5、RunloopAfterWaiting
6、RunloopExit
6个时机的事件回调&#