页面加载时间

今天聊一下页面加载时间的检测。

  • viewDidappear
  • viewIsAppearing
  • 监听某个元素渲染完时间

viewDidappear

比较简单的衡量方法都是,计算从 viewDidloadviewDidAppear时间。

如果衡量标准是从 上一个页面点击开始 到 当前页面展示完毕。可以稍微将衡量方法该为 记录点击事件viewDidAppear 时间。
或者为了 hook 方便 改为 从 UIViewController initUIViewController viewDidAppear时间。

最终都是到viewdidAppear的时间,但是这种计算遇到页面比较复杂,或者使用push动画的页面就比较尴尬了。

  • 页面比较复杂的情况时, 进入离开viewWillAppear、进入离开viewDidAppear都可能花费0.3s~1s的时间,误差就比较大了。
  • 如果使用了 pushViewController: animated: 动画设置为YES,viewDidAppear更是会在动画结束后才调用,凭白多了0.3s-0.5s左右的动画时间。

viewIsAppearing

页面比较复杂的情况下:展示页面渲染第一帧 和 页面展示完毕 这两个概念可能又有点区别。
用户比较感知明显的也是展示页面渲染第一帧这种方式。

在 WWDC23 中,苹果 为 UIViewController 生命周期引入了viewIsAppearing进行微妙的补充。
在xcode15 iOS13以上可用。
以前我们常见的生命周期方法包括viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear。
现在的生命周期路线:

  • viewDidLoad、
  • viewWillAppear、
  • viewIsAppearing
  • viewWillLayoutSubView
  • viewDidLayoutSubView
  • viewDidAppear、
  • viewWillDisappear、
  • viewDidDisappear。

viewIsAppearing在视图插入视图层次结构之后、布局之前调用,这使其成为最后一刻 UI 更新的理想位置。

理论上hook UIViewController initUIViewController viewIsAppearing 比 viewDidAppaer更接近页面首帧时间。

监听某个元素渲染完时间

viewIsAppearing 它是在视图添加到层次结构但尚未显示在屏幕上之后调用的, 实际出现首帧还会在这个方法调用之后一小段时间内。

若是要比较精准的首帧时间,可以采用指定最终渲染页面的某个元素的tag,并在网络请求成功后开启CADisplayLink检查该元素是否出现在根节点下面的方式。