或许明天
或许明天
  • 发布:2026-08-21 10:21
  • 更新:2026-08-21 10:21
  • 阅读:11

iOS 卡顿排查:三个问题快速定位性能瓶颈

分类:快应用
iOS

卡顿的本质

iOS 屏幕每 16.67ms 刷新一次(120Hz 设备是 8.33ms)。一帧内的工作没做完,就会错过刷新,表现为掉帧。所以排查卡顿,核心就一个问题:这一帧的时间被谁用掉了?

拆开来看只有三个环节:主线程、渲染、GPU。

第一问:主线程忙不忙?

主线程负责布局、图片解码、文本排版。这些事任何一件超过 16ms,直接掉帧。

常见的大头:

  • Auto Layout:复杂视图层级下约束求解很慢,列表滚动时反复触发更严重。
  • 图片解码:不预先解码,第一次显示时主线程解码,大图直接破帧。
  • 圆角和阴影:会触发离屏渲染,CPU 要先画一份额外图像再合成。
  • 富文本排版:多行文本、动态字体,排版计算不便宜。

怎么解决?原则只有一个:能提前做的别拖到主线程当下做。图片异步解码、圆角预先画好、布局结果缓存、文本排版预计算。

第二问:渲染准备有没有坑?

主线程干完活,Core Animation 要把更新打包交给 GPU。这一步的坑比较隐蔽:

  • 视图层级太深:几十层 view 叠在一起,每层都有固定成本。
  • 半透明太多:透明视图需要混合计算,大面积叠加会明显变慢。
  • 重写了 drawRect:一旦重写,就绕开 GPU 走 CPU 绘制,能不用就不用。

排查方法很简单,Simulator 里打开 Color Blended Layers,绿色正常,红色就是要优化的混合区域,让红色尽量消失。

第三问:GPU 扛得住吗?

GPU 的负载看两个数:设备利用率Tile 利用率

设备利用率接近 100%,GPU 已经满了;Tile 利用率超过 85%,多半是纹理问题——纹理太大、没压缩、没用 Mipmap。

优化方向:

  • 大图用 ASTC 压缩格式
  • 不透明 view 设置 isOpaque = true,减少无效绘制
  • 减少离屏渲染的触发

别只看 FPS

FPS 是一秒内的平均值,会掩盖问题。一秒内前 30 帧 8ms、后 30 帧 25ms,平均还是 55 FPS,但用户会感到明显卡顿。

真正该关注的是帧间隔的稳定性。单帧延迟的尖峰,才是卡顿的真实来源。高刷设备上尤其明显。

排查顺序

  1. 看帧延迟曲线,确认卡顿是周期性还是无规律
  2. 看主线程占用,判断是不是 CPU 瓶颈
  3. 看 GPU 利用率,判断是不是 GPU 瓶颈
  4. 针对具体环节优化,改完对比帧延迟分布,而不是只看 FPS

核心就一句话:每一帧都赶上车,比平均速度好看更重要。

0 关注 分享

要回复文章请先登录注册