【学习总结】02 | App 启动速度怎么做优化与监控?

1、前言

首先,我认为学习总结,要有所总,所结,就是有归纳后,能用自己的话告诉别人!有所结,就是有所收获输出,一般我认为是思维导图,所以,每篇文章前,我都会先给出文章的脑图:

iOS开发高手课-02-App启动速度怎么做优化与监控?.png

2、正文

注意,本系列总结不会引用或提供原课程文章所有的内容或代码,只会作出思维导图,需要学习可购买课程 《iOS开发高手课 - 极客时间》

本文作为第一篇,脑图中包含了一些学习的方法论,这里就不展开了,具体可以查看 如何建立你自己的开发知识体系 | iHTCboy's blog

学习原则

授人以鱼不如授人以渔

就想学习英语一样,每一个字母都认识,但是串联起来就不认识了。学习也一样,可能整篇文章大家都看懂了,但是对于其中的词语或句子,可能是不懂的,比如,rebase 指针attribute((constructor))selector 唯一性检查动态库加载ReactiveCocoa框架抓取主线程调用栈Mach-Olazy 和 non-lazy 符号rebind_symbol、等。或者,整篇文章都没有看懂,但是每个字都认识。

第一种情况,对于不认识的关键字,在搜索引擎就能找到很多,只能说是懒或恐惧心态,让你永远不去了解。第二种情况,一般多见于是抽象的文章,比如项目架构、编程思想等,大家都懂 MVC/MVVM,就是说不出懂什么的感觉,这种情况,还是建议多广义的学习,更多的实践,很多东西,还是较难做到言传,只能意会!

还有一种情况,我认为就是文章大家都看懂了,也没有什么疑问,但是忽略了一个面的概念,把问题想太简单,不会把知识点串联起来,不会触类旁通、融会贯通。举个例子,做过开发的都应该知道单例模式,如果不知道,搜索引擎都能搜索出一堆教程,并且介绍了来由,用途等,大家就知了知了。操作系统任务管理器、回收站、文件系统是不是一个单例?数据库连接池呢?生活中的例子,比如主席、CTO,对一个国家或一个公司,都是唯一的。

所以,第三种情况,目前来看大多数人看文章学习都达不到的层次,需要借助大量的阅读或别人的传授或指点,才能悟出来。所以,这就是我要说的,授人以鱼不如授人以渔,尽自己最大的已知学习和分享,这是一件快乐的事~

启动

  • 冷启动
    App 点击启动前,它的进程不在系统里,需要系统新创建一个进程分配给它启动的情况。这是一次完整的启动过程。

  • 热启动
    App 在冷启动后用户将 App 退后台,在 App 的进程还在系统里的情况下,用户重新启动进入 App 的过程,这个过程做的事情非常少。

文章中简单的提到了冷启动热启动。可能大家也是一看而过。这个启动其实是很重要的概念,不知道大家有没有留意,汽车发动机的冷启动和热启动电脑的冷启动和热启动?那么,手机是不是也有冷启动和热启动?iOS有冷启动和热启动,那么Android是不是也有冷启动和热启动?那么App有冷启动和热启动,那么微信的小程序是不是也有冷启动和热启动?

答案是肯定的!它们都有!为什么呢???似乎所有的系统都有冷启动和热启动!那么,冷启动和热启动,那么对汽车的伤害更大吗?冷启动和热启动那个对性能损耗(消耗)更大呢?答案也是肯定的,是冷启动

我是希望通过这个例子,让大家更加明白,一个简单的概念,可能很普通,但是一定不要放过!那么,到这里,针对App 启动速度怎么做优化,冷启动和热启动的重要性是不是自然而然就出来了,我们应该关注 App的冷启动和热启动,减少冷启动,尽量让App在后台时能通过热启动打开。,怎么理解呢?对于 iOS,系统严管管控手机的内存,当发现内存不足时,系统会全局发通知,让大家把不要的内存释放出来,如果大家都不释放,后台的应用就会被干掉,当然前台的应用如果占用内存超过阈值的话也会被干掉(kill)。所以,解决 App 启动速度怎么做优化,我们在写代码时,能注意到 App 内存使用情况,节省内存空间,减少不必要的内存创建,及时的释放内存等,都是对优化起到举足轻重的作用。

以上,就是冷启动和热启动,希望大家能感受到我一直说的触类旁通融会贯通的理念。

App的启动主要包括三个阶段

  1. main() 函数执行前
  2. main() 函数执行后
  3. 首屏渲染完成后

文章中说的内容,这里就不打算详细展开,简单的看本文的思维导图就可以,另外,文章中的很多细节的内容,在后续的篇章中会慢慢的介绍,这里就不展开,否则说不完事,大家感兴趣的,可以提前自行搜索,网络上真的都有了!本文需要提的是,解答一下前面说的几个有意思的问题

1、 +load() 方法和 +initialize() 方法

+load() 方法和 +initialize() 方法,大家都需要了解它们的区别和特性,这样才能更好的做性能优化。这里不作详细介绍,网络上能找到的,我这里不都不会说,除非值得注意的内容。

2、 attribute((constructor)) 修饰的函数的调用

这个是C语言的函数属性,有2种类型:__attribute__((constructor))__attribute__((destructor))

1)函数属性功能

`__attribute__ ((constructor))`:会使函数在 `main()函数`之前执行

`__attribute__ ((destructor))`:会使函数在 `main()函数`之后执行

2)功能范围

函数属性`__attribute__((constructor))`和`__attribute__((destructor))`在可执行文件或者库文件里都可以生效


3)与全局变量比较

全局变量对象的构造函数和析构函数分别在`__attribute__((constructor))`和`__attribute__((destructor))`标志的函数之前调用。

4)PRIORITY 优先级

```
__attribute__((constructor(PRIORITY)))
__attribute__((destructor(PRIORITY)))
```

`__attribute__((constructor))` 按照优先级小到大执行,`__attribute__((destructor(PRIORITY)))` 则是从大到小执行。

注意:
1、可执行程序或库文件都可以使用此属性修饰函数
2、同一个可执行程序或库文件允许多个函数被修饰,执行顺序由代码编写顺序或编译链接顺序有关

引用来源:函数属性attribute((constructor))和attribute((destructor)) - tianmo2010的专栏

3、objc_msgSend 方法和 hook 内容

hook的概率在很多的语言都有,因为安全和越狱等,针对 iOS 的 hook 网上也非常多,这里也不详细说了,后面的章节如果有相关安全的在说吧。相信大家网络上一定能找到很多资料!

4、怎样获取主线程调用栈?

相信有好奇心的同学,在阅读文章时,一定对怎样获取主线程调用栈的问题产生兴趣,但可能如果之前没有接触过,一定觉得太难了!根本找不到方向或者感觉!但是,你仔细想想,是不是真的这么难?没有方向?其实并不是,只要搜索一下,网络上也是一堆一堆的。当然,你想通过一篇文章就掌握所有这些相关的知识,那可能不太现实!你一定要明白,不劳而获永远是获得最少的!,所以,还是要靠自己努力,另外,后续的章节还会有这方面的深入知识,到时候在解答吧。希望大家能利用自己的学习能力,习得不亦乐乎!

5、监控耗时和耗时统计

这个问题也值得大家注意,后续章节在一起讨论。

6、源码阅读

苹果公司已经开源了 Objective-C 的运行时代码。你可以在苹果公司的开源网站,找到 objc_msgSend的源码。

Facebook 开源了一个hook库,可以在 iOS 上运行的 Mach-O 二进制文件中动态地重新绑定符号,这个库叫 fishhook。

针对这种源码,大多数人一定说,我看不懂!我看不懂!我看不懂!

这个,与下面这个问题相似,一起来回答吧

7、C语言、汇编语言 看不懂?!

看不懂?看不懂?看不懂?

有没有发现,我们小时候也不懂中文,现在怎么就看懂了呢!学啊!学啊!学啊!

怎么学? 从入门到放弃啊!怎么入门?

网络上有很多优秀的资源,大家如果真的感兴趣,一定要主动去了解,一味地抗拒永远不会得到结果和答案。汇编语言入门教程 - 阮一峰的网络日志 ,汇编语言入门学习就是这样简单,没有看不懂,只有不看懂!

人生苦短,我们努力吧~

8、其它问题

其它的还有很多问题,这里就不一一指出,比如 Swift 有 main 函数吗?希望大家 多疑问,多思考,多总结!,这样成长更快啦~

3、总结

回到本文的主题,“App 启动速度怎么做优化与监控?”,优化,不知道大家是否还记得之前的第一篇文章说到的,不记得的可以回去看看。监控的话,这里没有详细提到,因为性能监控只是监控系统的一小部分,后面的章节在细节展开吧。

这里先给出一个大纲,关于开发相关的工程优化,因为这也是我们从 《iOS开发高手课 - 极客时间》 来,我们要干什么?到那里去呢?

  • 可以做什么?
  1. 工程优化:代码、规范、性能、AOP、日志
  2. 工程监控:耗时、内存、网络、卡顿、崩溃、瘦身、耗电
  3. 工程效率:响应式框架、函数式编程、APM、监控系统
  4. 技术深研:RN、Flutter、小程序、动态化

很多知识点,大家现在看到这篇文章感觉一气呵成,水到渠成的样子,但是其实是一点一点的思考和触想,可能有一个概念很久之前就有,但是怎么把这些知识串联一起,确实是需要非常深厚的功能,才能做到。所以,本次系列,我只能说尽量自己的力量,因为我相信不管是后来者,还是以后的我,都一定超越现在的我!,所以,如果未来可以,可以在重写此系列,也是一件令人愉快的事!

注:更多关于 iOS 开发和程序开发相关的内容,可以查看此系列,目前还在连载中 【学习总结】iOS开发高手课 -- (连载中)| iHTCboy's blog,以上,希望对你有用!

参考

  • 《iOS开发高手课 - 极客时间》
  • 星光社 - 戴铭的博客

WWDC:

  • WWDC2016-406-Optimizing App Startup Time
  • WWDC2017-413-App Startup Time:Past,Present,and Future

Article:

  • iOS 在循环中使用计算属性导致内存暴涨 -
  • 可能碰到的iOS笔试面试题(6)--内存管理 -
  • iOS RunLoop详解 - 掘金
  • dyld简介及加载过程分析 -
  • App启动之Dyld在做什么 - 掘金
  • facebook/fishhook: A library that enables dynamically rebinding symbols in Mach-O binaries running on iOS.
  • vsouza/awesome-ios: A curated list of awesome iOS ecosystem, including Objective-C and Swift Projects
  • ming1016/GCDFetchFeed: “已阅”新版,RSS阅读器,使用FMDB做存储,ReactiveCocoa处理数据流向
  • ming1016/SMCheckProject: 使用Swift3开发了个MacOS的程序可以检测出objc项目中无用方法,然后一键全部清理
  • 汇编语言入门教程 - 阮一峰的网络日志
  • UIApplicationMain函数 -
  • iOS启动时间优化 - 第七章
  • How we cut our iOS app’s launch time in half (with this one cool trick)
  • 深入理解iOS App的启动过程
  • 如何精准度量iOSAPP启动时间
  • 优化 App 的启动时间-杨萧玉
  • iOS客户端启动速度优化-今日头条
  • iOS App 启动性能优化-WiFi管家
  • iOS App如何优化启动时间-Facebook
  • 一次立竿见影的启动时间优化
  • obj中国-Mach-O 可执行文件
  • iOS app启动速度研究实践
  • iOS App冷启动治理:来自美团外卖的实践
  • iOS动态库的使用
  • App启动之Dyld在做什么
  • 获取任意线程调用栈的那些事 - KT的iOS开发小站
  • 谈谈iOS获取调用链 - 掘金
  • 函数属性attribute((constructor))和attribute((destructor)) - tianmo2010的专栏
  • 真香!iOS云真机全新上线! - 腾讯WeTest
  • iOS 云真机实现原理 · TesterHome
  • 如何精确度量 iOS App 的启动时间 -


  • 如有侵权,联系必删!
  • 如有不正确的地方,欢迎指导!
  • 如有疑问,欢迎在评论区一起讨论!


注:本文首发于 iHTCboy's blog,如若转载,请注来源

你可能感兴趣的:(【学习总结】02 | App 启动速度怎么做优化与监控?)