iOS 性能优化三

作者: 飞不越疯人院 | 来源:发表于2020-08-21 11:38 被阅读0次

主要讲解APP冷启动的优化

iOS 性能优化一
iOS 性能优化二
iOS 性能优化三


1. APP 启动的分类

冷启动: 从零开始, 点击 APP加载;
热启动: APP 已经在内存中, 再次点击图标后加载;
我们常说的APP启动优化主要是针对冷启动;
通过在xcode 中添加环境变量可以打印出启动的时间;
Edit scheme -> Run -> Environment Variables 添加DYLD_PRINT_STATISTICS 值为1
启动后就会打印启动信息;
执行main函数之前的时间:

Total pre-main time: 567.86 milliseconds (100.0%)
         dylib loading time: 153.19 milliseconds (26.9%)
        rebase/binding time: 229.51 milliseconds (40.4%)
            ObjC setup time: 135.73 milliseconds (23.9%)
           initializer time:  49.28 milliseconds (8.6%)
           slowest intializers :
             libSystem.B.dylib :   6.81 milliseconds (1.1%)
    libMainThreadChecker.dylib :  29.43 milliseconds (5.1%)

DYLD_PRINT_STATISTICS改为DYLD_PRINT_STATISTICS_DETAILS可以打印更加详细的信息;

2. APP 冷启动经历哪些阶段

点击 APP 图标到加载成功经历大概三个阶段;

    1. dyld(dynamic link editor)阶段: APP的动态链接器, 用来装载 Mach-O 文件(可执行文件, 动态库等);
      1.1 装载APP的可执行文件, 同时递归加载所有的依赖动态库;
      1.2 当可执行文件和动态库都加载完成后, 通知runtime进行下一步操作;
    1. runtime阶段, 请先看下runtime源码中的ojbc_init函数;
      2.1 调用map_image对可执行文件内容解析;
      2.2 调用load_images调用所有ClassCategory的的+load方法
      2.3 各种objc结构的初始化(注册类, 初始化类对象等);
      2.4 至此可执行文件和动态库中的信息(class, protocol, SEL, IMP)已经按照格式加载到了内存中, 通过runtime管理;接下来调用main函数;
    1. main函数阶段;
      3.1 调用UIApplicationMain函数
      3.2 调用Appdelegateapplication:()didFinishLaunchingWithOptions()函数;

3. 优化启动时间

针对上面的分析APP启动过程中做了那些操作, 可以优化APP的启动时间

    1. dyld阶段:
      1.1 减少不必要的动态库, 合并一些库;
      1.2 减少objc的类, 分类, 方法的数量;
      1.3 swift能用struct的地方就不要创建类;
    1. runtime 阶段:
      尽量不要在+load方法中写逻辑,使用+initialize+ dispatch_once方式替代;
    1. main阶段:
      3.1 不要将所有的操作都放在didFinishLaunchingWithOptions中加载, 将一些不影响用户体验的操作延迟加载;
      3.2 按需加载; 多个tab时, 尽量只加载当前 tab 的内容;

补充

1. runtime 入口的objc_init方法
/***********************************************************************
* _objc_init
* Bootstrap initialization. Registers our image notifier with dyld.
* Called by libSystem BEFORE library initialization time
**********************************************************************/

void _objc_init(void)
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;
    
    // fixme defer initialization until an objc-using image is found?
    environ_init();
    tls_init();
    static_init();
    runtime_init();
    exception_init();
    cache_init();
    _imp_implementationWithBlock_init();
    _dyld_objc_notify_register(&map_images, load_images, unmap_image);
#if __OBJC2__
    didCallDyldNotifyRegister = true;
#endif
}

相关文章

网友评论

    本文标题:iOS 性能优化三

    本文链接:https://www.haomeiwen.com/subject/cpfsjktx.html