🌚

Kam's Online Notebook


UIButton 响应延迟

最近在做需求时,发现在 App 的五个 tab 间切换的时,消息 tab 的 view controller 总是慢一拍。其他页面基本是 touch up inside 后立刻出现,而消息 tab 则总是慢 100~200 ms,心生疑惑。

Instruments 组合拳

拿出祖传的卡顿排查组合拳进行分析调试:

  • Time Profiler:高频率(调整下 recording options)采集 callstack、CPU usage,定位问题代码;
  • Thread State Trace:关注目标线程(通常是 Main thread)的状态。为什么 Time Profiler 还不足以满足需求?举个例子,使用 Time Profiler 看到一个 function 调用 self weight 只有 1ms,但很可能由于触发了如跨进程通信导致当前 thread 进入 blocked 状态,而此时 CPU usage 为 0,那么就不容易找到这个 wall-time cost。
  • Point of Interest:方便在面板上显示代码上标定的起始区域。

下图 POI track 的 A B 两行分别是点击「消息 tab」和「我 tab」时产生的 record region,start point 是 tabBarController 的回调,end point 是 -viewDidAppear: 方法。

起初对比了很久 A B 两个区域的 Main Thread 的耗时,一个 60ms 一个 50ms 相差无几,硬是整不明白为什么会有可感知的延迟。

后来对比下其他 thread 的异同,才发现上图绿框、蓝框凸显的特征——顶部是触摸事件的派发线程,可见点击「消息 tab」的触摸事件派发,到 tabBarController 的回调开始,出现了时间差。

回到 TabBar 控件看源码才知道,消息 tab 的 UIButton 被同事加了单击、双击两个手势识别器,这下整明白了,好家伙。

EOF

— Jun 17, 2021