美文网首页
怎么让app启动更快?

怎么让app启动更快?

作者: cs_mark | 来源:发表于2018-09-25 15:11 被阅读0次

app启动

先来看app启动流程

APP的启动可以分为2种

1、冷启动(Cold Launch):从零开始启动APP

2、热启动(Warm Launch):APP已经在内存中,在后台存活着,再次点击图标启动APP

APP启动时间的优化,主要是针对冷启动进行优化
通过添加环境变量可以打印出APP的启动时间分析(Edit scheme -> Run -> Arguments)

1、DYLD_PRINT_STATISTICS设置为1

2、如果需要更详细的信息,那就将DYLD_PRINT_STATISTICS_DETAILS设置为1

APP的冷启动概括为三大阶段

dyld,Apple的动态链接器,可以用来装载Mach-O文件(可执行文件、动态库等)

启动APP时,dyld所做的事情有

1.装载APP的可执行文件,同时会递归加载所有依赖的动态库

2.当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行下一步的处理

runtime

启动APP时,runtime所做的事情有

1.调用map_images进行可执行文件内容的解析和处理

2.在load_images中调用call_load_methods,调用所有Class和Category的+load方法

3.进行各种objc结构的初始化(注册Objc类 、初始化类对象等等)

4.调用C++静态初始化器和attribute((constructor))修饰的函数

到此为止,可执行文件和动态库中所有的符号(Class,Protocol,Selector,IMP,…)都已经按格式成功加载到内存中,被runtime 所管理

main

1.APP的启动由dyld主导,将可执行文件加载到内存,顺便加载所有依赖的动态库

2.并由runtime负责加载成objc定义的结构

3.所有初始化工作结束后,dyld就会调用main函数

4.接下来就是UIApplicationMain函数,AppDelegate的application:didFinishLaunchingWithOptions:方法

优化方案

dylib loading

从主执行文件的 header 获取到需要加载的所依赖动态库列表,而 header 早就被内核映射过。然后它需要找到每个 dylib,然后打开文件读取文件起始位置,确保它是 Mach-O 文件。接着会找到代码签名并将其注册到内核。然后在 dylib 文件的每个 segment 上调用 mmap()。应用所依赖的 dylib 文件可能会再依赖其他 dylib,所以 dyld 所需要加载的是动态库列表一个递归依赖的集合。一般应用会加载 100 到 400 个 dylib 文件,但大部分都是系统 dylib,它们会被预先计算和缓存起来,加载速度很快。

优化操作

减少动态库、合并一些动态库(定期清理不必要的动态库)

减少Objc类、分类的数量、减少Selector数量(定期清理不必要的类、分类)

减少C++虚函数数量

Swift尽量使用struct

rebase/bind

由于ASLR(address space layout randomization)的存在,可执行文件和动态链接库在虚拟内存中的加载地址每次启动都不固定,所以需要这2步来修复镜像中的资源指针,来指向正确的地址。 rebase修复的是指向当前镜像内部的资源指针; 而bind指向的是镜像外部的资源指针。
rebase步骤先进行,需要把镜像读入内存,并以page为单位进行加密验证,保证不会被篡改,所以这一步的瓶颈在IO。bind在其后进行,由于要查询符号表,来指向跨镜像的资源,加上在rebase阶段,镜像已被读入和加密验证,所以这一步的瓶颈在于CPU计算。
通过命令行可以查看相关的资源指针:

xcrun dyldinfo -rebase -bind -lazy_bind myApp.App/myApp

优化该阶段的关键在于减少__DATA segment中的指针数量。我们可以优化的点有:

减少Objc类数量, 减少selector数量
减少C++虚函数数量
转而使用swift struct(其实本质上就是为了减少符号的数量)

二、runtime

这一步的主要工作有
1.注册Objc类 (class registration)
2.把category的定义插入方法列表 (category registration)
3.保证每一个selector唯一 (selctor uniquing)
由于之前2步骤的优化,这一步实际上没有什么可做的。

用+initialize方法和dispatch_once取代所有的attribute((constructor))、C++静态构造器、ObjC的+load

三、main()

关于mian()
准备阶段 这里主要是图片的解码
布局阶段 首页所有UIView的- (void)layoutSubViews()运行
绘制阶段 首页所有UIView的- (void)drawRect:(CGRect)rect运行
再加上启动之后必要服务的启动、必要数据的创建和读取,这些就是我们可以尝试优化的地方

因此,main()函数调用之前我们可以优化的点有:

1.不使用xib,直接视用代码加载首页视图。
2.NSUserDefaults实际上是在Library文件夹下会生产一个plist文件,如果文件太大的话一次能读取到内存中可能很耗时,这个影响需要评估,如果耗时很大的话需要拆分(需考虑老版本覆盖安装兼容问题)。
3.每次用NSLog方式打印会隐式的创建一个Calendar, 仅仅针对内测版输出log。
4.梳理应用启动时发送的所有网络请求,统一在异步线程请求。
并行初始化各个业务。
5.launcherImage图片尽量小,实测这个大小会影响启动速度
6.对于MainThread有需要的业务,提供mainThread 支持。

在不影响用户体验的前提下,尽可能将一些操作延迟,不要全部都放在finishLaunching方法中
按需加载

相关文章

  • 怎么让app启动更快?

    app启动 先来看app启动流程 APP的启动可以分为2种 1、冷启动(Cold Launch):从零开始启动AP...

  • Android 任务启动器

    在安卓的优化中,有一个点是很重要的就是APP的启动优化,更快的启动优化可以让用户更快的看到用户界面。提高用户响应速...

  • 让 Linux 启动更快

    进行 Linux 内核与固件开发的时候,往往需要多次的重启,会浪费大把的时间。 在所有我拥有或使用过的电脑中,启动...

  • iOS 性能调优之启动时间优化

    目的 从点击 App 图标到加载 App 闪屏之间会有个动画,我们希望 App 启动速度比这个动画更快。需要注意的...

  • APP启动更快iOS15

    之前可以通过设置DYLD_PRINT_STATISTICS = 1 变量在XCode上统计APP启动时间pre-m...

  • Android性能优化

    目的:使APP 更快、更稳定、更省(节省资源、电量、网络、内存等) 1.启动速度 优化原因:初次打卡APP时需要加...

  • 如何让别人快速接受归农?

    1/怎么样让人更快接受我们的产品? 2/怎么样让人更快接受我们的平台? 3/怎么样让人更快融入我们的氛围? 4/怎...

  • Android Studio2.3 instant run bu

    今天看到Android Studio有更新,貌似compile更快了,兴冲冲的开始试用,没想到app不能启动。找了...

  • 一. Android 启动时间优化

    1)启动页白屏及黑屏解决?2)启动太慢怎么解决?3)怎么保证应用启动不卡顿?4)App启动崩溃异常捕捉5)统计启动...

  • iOS app启动优化方案

    一、APP的启动 二、App启动阶段 APP的启动 - dyld APP的启动 - runtime APP的启动 ...

网友评论

      本文标题:怎么让app启动更快?

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