[性能优化]今日头条iOS客户端启动速度优化

  • 时间:
  • 浏览:23
  • 来源:极速赛车群_极速赛车信誉群_十年信誉群

应用程序的启动时间直接影响用户对应用程序的判断和体验。标题主应用程序本身包含许多高度复杂的业务模块(如新闻、视频等)。)以及许多第三方插件,这必然会降低应用程序的启动时间。 本着不断改进和追求用户体验的态度,我们希望在拓展业务的同时最大限度地优化启动时间。

让我们从结论开始。T(应用程序总启动时间)= t1(上图显示了自定义类XXVII控制器中+Objc的+负荷()函数方法断点的调用堆栈,清楚地显示了整个调用堆栈和序列:main()之前的时间+T2(main()之后的加载时间)。 T1=加载系统dylib(动态链接库)及其自己的应用程序可执行文件;
t2=main方法执行之后到AppDelegate类中的- 方法执行结束前这段时间,主要是构建第一个界面,并完成渲染展示。

t2 =主方法执行之后到AppDelegate类中的-方法执行结束前这段时间,主要是构建第一个界面,并完成渲染展示。the AppDelegate类中从主方法执行到方法执行结束的这段时间主要是构建第一个接口并完成呈现演示。 应用程序启动后,系统首先加载可执行文件(所有自己的应用程序)。
动态链接库包括:iOS 中用到的所有系统 framework,加载OC runtime方法的libobjc,系统级别的libSystem,例如libdispatch(GCD)和libsystem_blocks (Block)。

动态链接库包括:iOS中用到的所有系统框架,加载OC运行时方法的libobjc,系统级别的图书馆系统,例如libdispatch(GCD)和libsystem_blocks(块).动态链接库包括iOS中使用的所有系统框架,加载有OC运行时方法的libobjc,以及系统级libSystems,如libdispatch(GCD)和libsystem_blocks (Block)。事实上,无论是系统的动态链接库还是应用程序本身的可执行文件,它们都被称为Dylib的body double,哪一天想直接升级到libSystem。
2.1.
2.

2.

o文件。2.Dylib动态链接库框架是一个包含动态链接库和相应资源的文件夹结构。图像捆绑资源文件只能由dlopen加载,这是不推荐的。 除了我们的应用程序自己的可行性文件,系统中的所有框架,如UIKit和Foundation,都以动态链接库的形式集成到应用程序中。

代码共享:许多程序动态链接这些库,但是它们在内存和磁盘中只有一个副本。易于维护:因为依赖的库只有在程序执行时才被链接,所以这些库很容易更新,比如libSystem。 Dylib是libSystem。B.

此时,所有符号(类、协议、选择器、IMP、。

)和动态库已根据格式成功加载到内存中,并由运行时管理。之后,运行时方法(类的动态添加、swizzle等)。)可以生效。 C.

Dylib,然后更换双体。
两步走: 在程序运行时它先将动态链接的 PRINT 递归加载 (也就是上面测试栈中一串的递归调用的时刻)。 如果程序刚刚运行,程序的代码将由dyld缓存,因此即使再次重新启动终止过程,加载时间也会相对较快。

如果长时间没有启动或者当前dyld缓存被其他应用占用,启动时间会更长,分别是热启动和冷启动的概念,如下图所示:如上图所示,不同的进程共享系统dylib的区域,但每个进程都维护相应的区域。 我们应用程序中的所有动态链接库和静态库。

两步走以下内容:在程序运行时它先将动态链接的打印递归加载(也就是上面测试栈中一串的递归调用的时刻).

  1. 苹果的动态链接编辑器dyld(动态链接编辑器)最终会将文件加载到内存中。 因此,在调用main()函数之前,我们可以优化的点是:由一个名为ImageLoader的类加载(一对一对应)。

  2. 那么什么是图像加载器?

  3. 图像是指包含编译符号、代码等的二进制文件(可执行文件左右)。

  4. 因此,ImageLoader的角色是将这些文件加载到内存中,每个文件负责加载ImageLoader的一个实例。

两个步骤:当程序运行时,它递归地加载动态链接。每次在NSLog模式下打印时,您将隐式地创建一个日历,因此您需要在启动时删除每个业务方键入的日志,或者只输出内部版本的日志。

(即在上面的测试堆栈中进行一系列递归调用的时刻)。

  1. 然后递归加载可执行文件映像中的所有符号。

  2. 当然,所有这些都发生在我们真正的主要功能被执行之前。

  3. 动态链接库的加载步骤具体分为五个步骤:

  4. Loaddylibsamage读取库映像文件

  5. 重设图像基础

  6. 绑定图像

xcrun dyldinfo-rebase-bind-lazy _ bind MYapp。

  1. 切换到swift stuct(本质上是为了减少符号数量)

  2. 加载dylibs图像

  3. 在加载每个动态库的过程中,dyld需要:

分析所依赖的动态库

找到动态库的mach-o文件打开文件
rebase步骤先进行,需要把镜像读入内存,并以page为单位进行加密验证,保证不会被篡改,所以这一步的瓶颈在IO。在系统核心签署文件
通过命令行可以查看相关的资源指针:

通常,一个应用程序需要加载100到400个dylibs,但是系统库是优化的,可以快速加载。该步骤的优化包括:减少对非系统库的依赖

rebase步骤先进行,需要把镜像读入内存,并以页为单位进行加密验证,保证不会被篡改,所以这一步的瓶颈在信息作战. 使用静态资源,例如向主程序添加代码

  1. 通过命令行可以查看相关的资源指针以下内容: 由于ASLR(地址空间布局随机化)的存在,虚拟内存中可执行文件和动态链接库的加载地址每次启动时都不是固定的,因此需要这两个步骤来修复镜像中的资源指针以指向正确的地址。

  2. Rebase将资源指针固定在当前镜像中。

绑定是指镜像外部的资源指针。

首先进行重新基础步骤。

  1. 镜像需要读入内存,并以页面为单位进行加密和验证,以确保不会被篡改。

  2. 因此,这一步的瓶颈是输入输出。

  3. 绑定稍后进行。

由于符号表将被查询以指向交叉镜像资源,并且镜像已经在重定基阶段被读入和加密,因此该步骤的瓶颈在于CPU计算。

相关的资源指针可以通过命令行查看:

Objc设置

  1. App/myApp

  2. 优化此阶段的关键是减少__DATA段中的指针数量。我们可以优化以下几点:减少Objc类和选择器的数量

  3. 减少C++虚函数的数量

初始值设定项

目标设置该步骤的主要工作是:

注册Objc类

  1. 将类别定义插入类别注册

  2. 确保每个选择器都是唯一的

  3. 由于前面两个步骤的优化,这一步实际上没有什么可做的。

  4. 初始值设定项以上三个步骤都属于修复,所有这些步骤都是修改__DATA段的内容,而此时动态调整开始,内容被写入堆和堆栈。图像loadC++的构造函数属性函数如下

属性

((构造函数))void DoSomeInitializationWork()

非基本C++静态全局变量(通常是类或结构)(非平凡初始化器)的创建,例如全局静态结构的构造,如果构造器中有大量工作,将会降低启动速度。

Objc的加载函数和C++的静态构造函数是自下而上执行的,以确保每个执行方法都能找到它所依赖的动态库。

图像loadDyld开始初始化程序二进制文件

图像加载器读取包含我们的类、方法和其他符号的图像。

因为运行时将回调绑定到dyld,dyld将在映像加载到内存中时通知运行时处理该映像。 运行时接管时调用映射。 图像

调入图像

负荷 方法方法遍历所有加载的类,并根据继承级别依次调用类的+load方法及其类别的+load方法

图像

整个事件由戴尔主导。运行环境初始化完成后,dyld将与ImageLoader合作,根据格式将二进制文件加载到内存中,动态链接依赖库,运行时将负责将其加载到objc定义的结构中。

在所有初始化之后,DYLD将调用真正的主函数。

  1. 图像

  2. 然后问题出现了,如何测量main()之前的时间,即时间1? 苹果官员提供了一种方法,即在调试真实机器时检查dyld

  3. 图像

    统计选项。
  4. 图像 您会得到以下形式的输出:

  5. 图像

     
  6. 这表明,对于系统级动态链接库,因为苹果已经对其进行了优化,所以不需要太多时间。

  7. 在这个可怕的例子中,它自己的应用程序中的代码占据了94%的时间。

2%我们应用程序中的典型日志如下: 图像可以看出,花费的时间最多的仍然是图像加载和OC类初始化,这需要79。 总时间的5%。
而视图的渲染主要涉及三个阶段:

  1. 总之,我们可以在调用main()之前优化时间消耗:

  2. 减少不必要的框架,因为动态链接非常耗时。

  3. 检查框架应设置为可选和必需的。
    再加上启动之后必要服务的启动、必要数据的创建和读取,这些就是我们可以尝试优化的地方

合并或删除一些原币类。

  1. 为了清理项目中未使用的类,使用工具AppCode代码检查函数来找出当前项目中未使用的类,如下所示

  2. 而视图的渲染主要涉及三个阶段以下内容:

删除尚未调用或已放弃的方法。

延迟+load方法中不需要做的事情来+初始化尽量不要使用C++虚拟函数(创建虚拟函数表有开销)

再加上启动之后必要服务的启动、必要数据的创建和读取,这些就是我们可以尝试优化的地方 我们的优化还在于如何快速显示主页。 应用程序通常会在(bool)应用程序:(ui application *)applicationdidfinishlaunchingviews:(nsdictionary *)AppDelegate类中的launchoptions方法中创建一个显示在首页的视图,然后在当前运行循环结束时,它会主动调用CA::Transaction::commit来完成视图的呈现。

视图的呈现主要包括三个阶段:

在准备阶段,这主要是图片的解码。

-(无效)布局子视图()针对布局阶段第一页上的所有用户视图运行 (void) drawect: (cgcrect)直接运行绘图阶段3第一页上的所有UIView。 这一点,加上必要服务的启动以及启动后必要数据的创建和读取,是我们可以尝试优化的地方。3.不使用xib,直接根据codeNSUserDefaults加载主页视图实际上会在库文件夹下生成一个plist文件。

如果文件太大,一次将它读入内存可能需要时间。

这种影响需要评估,如果需要太长时间,就需要分开(需要考虑覆盖安装的旧版本的兼容性问题) 图像

  1. 组合应用程序启动时发送的所有网络请求,它们能否统一为异步线程请求

  2. 二.
    测量数据一个空的地狱世界项目已经建立,只增加了吊舱中的代码,不包括主终端的业务逻辑代码。

  3. 典型的冷启动基本上接近2s iPhone6 iOS9。 3.

  4. 5系统测试的主要时间是加载动态库,初始化类/方法和符号地址绑定阶段。

图像 典型的热启动数据如下:可以看出,典型的热启动需要2。由于系统的缓存优化,加上首页主要业务逻辑代码,比冷启动快500毫秒。

猜你喜欢

今日头条app最新版免费下载

今日头条app免费下载!这款今日头条app拥有各种精彩资讯信息,为广大喜欢阅读的小伙伴提供了大量的新闻热点,即使是足不出门也能轻松了解到天下事,喜欢的话快来本站下载今日头条app最新版吧!今日头条,最懂你的信息平台官方推荐精品应用单用户使用时长超过76分钟近亿网友与你一起在头

2019-11-19

分享幸运飞艇回血上岸技巧心得和辛酸经历

每个人真正强大起来都要度过一段没人帮忙,没人支持的日子。所有事情都是自己一个人撑,所有情绪都是只有自己知道。但只要咬牙撑过去,一切都不一样了。我见过很多朋友,每天赚几百的,但是不定什么时候能一天亏几千甚至几万!多少天的努力一天就付之东流了,这样是对人心理承受能力的摧残买彩的目的都是盈利,辛辛苦苦机天甚至几个星期赚来的钱一下被拿走!就容易急容易脑热,在这种情况下是最容易输的!有些朋友会问,

2019-11-19

万鸿2娱乐平台招商

万鸿2娱乐平台招商?万鸿2娱乐平台招商【在线开户um05.net】【招商σσ微:915769690】口碑至上,口碑当首,无任何后顾之忧!【1比1兑换秒提现】24小时服务,公平的棋牌公正的棋牌下载!当】【詹】【姆】【斯】【去】【年】【夏】【天】【转】【投】【湖】【人】【后】【,】【年】【轻】【而】【富】【有】【激】【情】【的】【凯】【尔】【特】【人】【被】【视】【为】【东】【部】

2019-11-19

一条微信细数呼和浩特魅力

您当前的位置:新闻中心>要闻>科教文卫正文分享到一条微信细数呼和浩特魅力内蒙古新闻网16-07-0609:29【打印本页】来源:呼和浩特晚报网友转发“你没爱上呼和浩特,是因为没来这23个地方”常常有人把对

2019-11-19

去澳大利亚读本科一年的费用是多少

澳大利亚是一直以来都是广大留学学子的向往之地,去澳洲留学本科一年会需要多少钱呢?小编为大家带来了澳大利亚读本科一年的费用,希望对大家有帮助。学费本科保守估计18000澳币一年,有的名校好专业甚至要2,3万澳币都有。澳大利亚移民局规定留学生每年的生活费按每月1500澳币来算。去澳大利亚读本科每年的费用是多

2019-11-19