APP启动时间最精确的记录方式

APP启动时间记录:

1、用户点击icon ----> main函数 === T1
2、main函数 -----> FirstController === T2
3、firstController加载成功 === T3

通常 用户的感知时间 T1 + T2 + T3,通常记录APP的启动时长的方法三种,下方依次简单介绍,相信只要提供一个思路,下面都会知道怎么办的!

记录的三中思路 依次精确 :
方法一:didFinishLaunch ---- > FirstController
方法二:AAXX动态库 ----> FirstController
方法三: 用户点击Icon -----> FirstController


方法一: 最普通的记录方式,从didFinishLaunch开始记录
DidFinishLaunch方法 ---> FirstController : ViewDidAppear: 方法时间的记录

相信通常是这样来记录APP的启动时长,但是我们都知道这样一点都不准确,DidFinishLaunch方法之前还有很多操作要做,那么如何精确的测量呢?

方法二 => 从加载动态库的时候开始记录
思路如下:
  1、动态库加载
  2、记录方法一的时间

解释一下:
APP启动的大体流程:
1、pre-main
加载可执行文件、加载动态链接器dyld、按照依赖加载动态库……
2、main() ==>DidFinishLaunch ……

通常记录启动时长从2记录,但是,仔细看一下1步骤,按照依赖加载动态库,方法二由此而来

思路:
创建一个确保第一个加载的动态库,在+load方法中记录时间,相比方法一,更加精确记录启动时间!

PS:如何确保第一个加载动态库:参考下方的两个链接,具体讲解了很多,这里涉及到的是CocoaPods使用了molinillo的算法对动态库的依赖进行了计算大体呈现的现象像是按照首字母排列的,但是并不是!!
注意:虽然依赖按照算法计算,但是一般以AA开头的动态库加载也是优先的,当然这是大部分情况,可以试一下!
CocoaPods 都做了什么?
Molinillo

方法三: 最为精确的记录APP启动时间,从用户点击Icon的时候开始记录!

方法二中我们从第一个动态库开始记录启动时间,但是在加载动态库之前还有一段时间我们记录不到,怎么办呢?

思路:
监听APP加载到内存中的进程信息!

这里对于进程就不再做过多的介绍!
根据这个思路,我查看了相关的官方API,发现真的有针对进程的方法:
iOS中获取进程信息-NSProcessInfo
可以参考这个文章,可以获取到进程的一些属性,那么使用如下方法,我们即可以获取到进程加载到内存的时间!

// 根据进程ID,获取进程信息!
+ (BOOL)processInfoForPID:(int)pid procInfo:(struct kinfo_proc*)procInfo
{
    int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    size_t size = sizeof(*procInfo);
    return sysctl(cmd, sizeof(cmd)/sizeof(*cmd), procInfo, &size, NULL, 0) == 0;
}
//  根据进程信息,获取具体的进程加载到内存中的时间戳
+ (NSTimeInterval)processStartTime {
    struct kinfo_proc kProcInfo;
    if ([[self class] processInfoForPID:[[NSProcessInfo processInfo] processIdentifier] procInfo:&kProcInfo]) {
        return (kProcInfo.kp_proc.p_un.__p_starttime.tv_sec * 1000.0 + kProcInfo.kp_proc.p_un.__p_starttime.tv_usec / 1000.0);
    } else {
        NSAssert(NO, @"无法取得进程的信息");
        return 0;
    }
}

PS: 获取到相关进程加载到内存中的时间,其实可以等同于获取到用户点击Icon的时间,用这个时间来记录APP的启动时间最为精确!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章