iOS 列表卡顿优化

Hitches(卡顿)定义

简单来说就是掉帧。Render Loop在规定时间内没有准备好一帧画面。以iOS为例 1秒60帧 每帧16.67ms,如果16.67ms内没有准备好一帧画面,即卡顿一次。

卡顿程度指标:  Hitch time ratio is the total hitch time in an interval divided by its duration. (可以通过 metrickit监控)

  •  < 5ms/s  不错
  •  [5ms/s , 10ms/s] 中等
  • 10ms/s, 严重

iOS视图渲染流程

Commit Phase

  • 细分为四个阶段

    • layout phase:  布局view。相关方法:layoutSubviews, setNeedsLayout, layoutIfNeesed.  
    • display phase: drawReact
    • prepare phase:未解码的图片在该阶段解码。需要注意: 大图的解码耗时比较久。
    • commit phase:打包提交到渲染服务
  • Find hitches with Instruments

    • 打开 Hitches Instrument, 正常操作app, 选择某个hitch, 查看方法耗时。
    • 优化耗时代码
    • 不断重复~
  • recommendations

    • 懒加载,比较重的view在使用时再加载,避免浪费。
    • 选用轻量级的view, 尽量使用CALayer的属性实现UI效果;
    • 尽量减少 adding, removing操作; 可以使用hidden达到相同效果;
    • 尽量不要用drawReact, 会消耗一定的时间、内存资源;
    • 不要调用layoutIfNeeded;  需要进行布局的视图调用setNeedesLayout 标记一下;
    • 约束不要太复杂,不要频繁的添加移除约束;

Render Phase

  • 两个阶段

    • render prepare. The render prepare phase is where our layer tree is compiled down into a pipeline of simple operations for the GPU to execute. Animations which take place over a couple of frames are also handled here.
    • render execute. During the render execute phase, the GPU draws the app's layers into a final image ready to be displayed. Either of these phases could delay the frame's delivery time.  常见问题:离屏渲染
  • 出现离屏渲染场景

    • shadowing
    • masking
    • rounded rectangles (mayber)
    • Visual effects
  • Find hitches with Instruments

    • Instruments hitches,  render Count 查看离屏渲染数量
    • Xcode View Debugger
      • Editor -> show layers  选中某个layer, 可以查看其离屏渲染数量(Offscreens) 及原因。
      • Editor -> show Optimization Opportunities,  根据优化建议进行优化
  • recommendations

    • 使用shadowPath设置阴影;
    • 实现圆角效果性能 对比: cornerRadius 不使用 maskToBounds(subview没有超过view) > maskToBounds > mask layer

优化实践

Lazy load

UITableViewCell、UICollectionViewCell中在一定条件下才会展示的view需要考虑懒加载。 需要格外注意比较重的view(如lottie)

Layout

  • 不要调用 layoutIfNeeded
  • sizeToFit,  intrinsicContentSize, 计算文本高度都比较耗时,尽量不要调用。 可以子线程计算文本高度,主线程直接使用。
  • 不要频繁的add、remove view。 hidden更轻量;
  • 不要频繁删除、添加、更新约束;

圆角

  • 使用合适的方式添加圆角
  • 加圆角方式比较:cornerRadius 不使用 maskToBounds(subview没有超过view) > maskToBounds > mask layer

Iconfont

  • 高频使用带颜色的iconfont场景下,缓存iconfont生成的图片。
  • iconfont推荐使用富文本显示

获取配置信息

  • 需要考虑 实验、配置、NSUserDefault 读取耗时。高频调用的场景(滑动、卡片更新数据)用属性保存一下,避免每次都调用。

资料

Explore UI animation hitches and the render loop
Find and fix hitches in the commit phase
Demystify and eliminate hitches in the render phase High Performance Auto Layout

猜你喜欢

转载自juejin.im/post/7033376049455087629