性能
线上卡顿看主线程 RunLoop
实验室用 Instruments。线上要知道主线程是不是长时间没有往下走,并把当时的栈留下。
卡顿是主线程在一帧的预算里没有把活干完。界面和触摸都在主线程的 RunLoop 里转。RunLoop 长时间不回到等待状态,用户就会觉得点了没反应。
线上怎么抓
给主线程 RunLoop 加一个观察者,看某两个状态之间隔了多久。超过阈值就把当前线程栈记下来,稍后上报。阈值用秒级去抓“卡住了”,用更短的阈值会把正常的重帧也报上来,先把长卡顿清掉。
上报按次数排。次数最高的先看,因为影响的人多。同一类栈归在一起:主线程读写大文件、主线程解析、为了拿一个 frame 去 layoutIfNeeded、无事件的地方还在用重的 UIView。
写代码时就避开
- 读写磁盘、解析、模型转换放在后台,回到主线程只改界面。
- 不需要交互的小块用 CALayer。不要为了刷新去重写 drawRect。
- 想要最新布局时,先问是不是真的必须马上 layoutIfNeeded。很多时候只是想读一个算得出来的尺寸。
- 图片显示尺寸和视图尺寸差太多,主线程会花时间缩放。
监控解决的是“已经发生的卡顿能被看见”。规范解决的是下一版不要再写回去。两个都要,只加监控不改写法,榜单会一直是那几个栈。