前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS页面加载时间测试初探

iOS页面加载时间测试初探

作者头像
测试加
发布2022-12-05 12:17:05
1.6K0
发布2022-12-05 12:17:05
举报

前言

页面加载时间指的页面从创建到可见的时间。严格意义上来说页面加载时间测试,更应该是页面的冷加载,不包含接口返回数据时间。

页面加载时间能反映代码中,创建页面视图是否有过度绘制或者绘制不合理导致创建视图时间过长的情况。

UIViewController是什么?

UIViewController是画面控制的中心类,包含导航条、标签条、工具条等多种功能界面,主要功能是用于控制画面的切换,其中的view属性管理整个画面的外观。

页面生命周期

viewDidLoad: 载入完成,可以进行自定义数据以及动态创建其他控件

viewWillAppear: 视图即将出现在屏幕之前

viewDidAppear: 视图已经在屏幕上渲染完成

viewWillDisappear: 视图即将从屏幕上移除

viewDidDisappear: 视图已经被从屏幕上移除

dealloc: 视图被销毁

image

测试方法

view基类打点

一般项目代码都会继承UIViewController做一些封装,然后其他页面继承这个view基类。

页面开始创建点

- (void)viewDidLoad {
    [super viewDidLoad];
    //继承了UIViewController的viewDidLoad方法
    self.statusBarStyle = UIStatusBarStyleDefault;
    [self.view setBackgroundColor:[UIColor whiteColor]];

    NSLog(@"page-test-start:%@",NSStringFromClass([self class]));
    self.StartTime = [[NSDate date] timeIntervalSince1970];
}

页面展示结束点
- (void)viewDidAppear:(BOOL)animated{
     [super viewDidAppear:animated];
     //继承了UIViewController的viewDidAppear方法
    NSLog(@"page-test-end:%@",NSStringFromClass([self class]));
    // 用NSStringFromClass方法获取当前的页名称
    self.EndTime = [[NSDate date] timeIntervalSince1970];
    CGFloat rounded_up = round((self.EndTime-self.StartTime) * 1000);
    NSLog(@"page-test-total:%.2lf",rounded_up);
}


操作app并且使用idevicesyslog过滤关键字:

idevicesyslog | grep -e page-test-end -e  page-test-total


output:

Sep 30 16:33:06 xinxide-iPhone xxxxx[2195] <Notice>: page-test-end:HomeViewController
Sep 30 16:33:06 xinxide-iPhone xxxxx[2195] <Notice>: page-test-total:379.00
Sep 30 16:33:09 xinxide-iPhone xxxxx[2195] <Notice>: page-test-end:UserInfoViewControllerV2
Sep 30 16:33:09 xinxide-iPhone xxxxx[2195] <Notice>: page-test-total:239.00
Sep 30 16:33:12 xinxide-iPhone xxxxx[2195] <Notice>: page-test-end:LoginRegisterViewControllerV2
Sep 30 16:33:12 xinxide-iPhone xxxxx[2195] <Notice>: page-test-total:631.00
Sep 30 16:33:14 xinxide-iPhone xxxxx[2195] <Notice>: page-test-end:LoginViewControllerV2
Sep 30 16:33:14 xinxide-iPhone xxxxx[2195] <Notice>: page-test-total:567.00

hook机制

第一种方法在你需要知道view的基类叫什么名字并且在代码中打点,这样做每次都有麻烦。

所以想使用拦截viewDidLoad和viewDidAppear这两个函数,就拦截器中打印时间就可以了。

Aspects库是一个是iOS上的轻量级AOP库,

https://github.com/steipete/Aspects,另外Aspects封装了iOS runtime的特性。

什么是AOP?

简单来说,AOP(Aspect Oriented Programming)是面向切面编程,主要的功能是:日志记录,性能统计、安全控制、事务处理、异常处理等等。

什么是hook?

使它能够将自身的代码「融入」被勾住(Hook)的程序的进程中,成为目标进程的一个部分。API Hook 技术是一种用于改变 API 执行结果的技术,能够将系统的 API 函数执行重定向。

核心代码

在podfile引用如下:



target "UICatalog" do
  xcodeproj 'UICatalog.xcodeproj'
  pod 'YYKit'
  pod 'Aspects'
end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[getperformance new] performancethread];//获取性能数据

    /**
     *  事件拦截
     *  拦截UIViewController的viewDidLoad方法
     */
    [UIViewController aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo){
        NSLog(@"%@ 对象的viewDidLoad调用了",aspectInfo.instance);
        self.StartTime = [[NSDate date] timeIntervalSince1970];
        /**
         *  添加我们要执行的代码,由于withOptions是AspectPositionAfter。
         *  所以每个控制器的viewDidLoad触发都会执行下面的方法
         */
    } error:NULL];

    /**
     *  事件拦截
     *  拦截UIViewController的viewDidAppear方法
     */
    [UIViewController aspect_hookSelector:@selector(viewDidAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo){
        NSLog(@"%@ 对象的viewDidAppear调用了",aspectInfo.instance);
        self.EndTime = [[NSDate date] timeIntervalSince1970];
        CGFloat rounded_up = round((self.EndTime-self.StartTime) * 1000);
        NSLog(@"%@页面,页面加载耗时:%.2lf",aspectInfo.instance,rounded_up);
        /**
         *  添加我们要执行的代码,由于withOptions是AspectPositionAfter。
         *  所以每个控制器的viewDidLoad触发都会执行下面的方法
         */
    } error:NULL];
    return YES;
}


output:

2018-10-02 18:11:44.361065+0800 UICatalog[22872:5780236] <AAPLAlertViewController: 0x7ffd0cf2c870>页面,页面加载耗时:518.00
2018-10-02 18:11:50.289907+0800 UICatalog[22872:5780236] <AAPLPageControlViewController: 0x7ffd0ce39080>页面,页面加载耗时:523.00
2018-10-02 18:11:52.131938+0800 UICatalog[22872:5780236] <AAPLDatePickerController: 0x7ffd0ce3a550>页面,页面加载耗时:631.00

结语

客户端专项测试已经做了大半年了,从无到有、从有到持续优化。

对我而言有两点思考.

1、专项测试测出来的数据结果,其实并不是记录一个数值而已,更需求了解其背后的技术特性。

2、测试结果是否可能提供给开发同学优化的价值,换位思考如果你是开发,你面对一些冰冷的数据,你如何优化?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试加 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • UIViewController是什么?
  • 页面生命周期
  • 测试方法
    • view基类打点
      • hook机制
        • 什么是AOP?
          • 核心代码
            • 在podfile引用如下:
            • 结语
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档