渲染可以分为四个步骤
- Layout(布局) , 源头是 Root Layer 调用[CALayer layoutSubLayers] , 这时候 UIViewController 的 viewDidLoad 和 LayoutSubViews 会调用 , autolayout 也是在这一步生效
- Display(绘制) , 源头是 Root Layer 调用[CALayer display] , 如果 View 实现了 drawRect 方法 , 会在这个阶段调用
- Prepare(准备) , 这个过程中会完成图片的解码
- Commit(提交) , 打包 Render Tree 通过 XPC 的方式发给 Render Server

文章插图
启动 Pipeline详细回顾下整个启动过程 , 以及各个阶段耗时的影响因素:

文章插图
- 点击图标 , 创建进程
- mmap 主二进制 , 找到 dyld 的路径
- mmap dyld , 把入口地址设为_dyld_start
- 重启手机/更新/下载 App 的第一次启动 , 会创建启动闭包
- 把没有加载的动态库 mmap 进来 , 动态库的数量会影响这个阶段
- 对每个二进制做 bind 和 rebase , 主要耗时在 Page In , 影响 Page In 数量的是 objc 的元数据
- 初始化 objc 的 runtime , 由于闭包已经初始化了大部分 , 这里只会注册 sel 和装载 category
- +load 和静态初始化被调用 , 除了方法本身耗时 , 这里还会引起大量 Page In
- 初始化 UIApplication , 启动 Main Runloop
- 执行 will/didFinishLaunch , 这里主要是业务代码耗时
- Layout , viewDidLoad 和 Layoutsubviews 会在这里调用 , Autolayout 太多会影响这部分时间
- Display , drawRect 会调用
- Prepare , 图片解码发生在这一步
- Commit , 首帧渲染数据打包发给 RenderServer , 启动结束
- 解析动态库的依赖关系
- 解析 LINKEDIT , 找到 bind & rebase 的指针地址 , 找到 bind 符号的地址
- 注册 objc 的 Class/Method 等元数据 , 对大型工程来说 , 这部分耗时会很长
之所以花这么大篇幅讲原理 , 是因为任何优化都一样 , 只有深入理解系统运作的原理 , 才能找到性能的瓶颈 , 下一篇我们会介绍下如何利用这些原理解决实际问题 。
加入我们我们是负责抖音客户端基础能力研发和新技术探索的团队 。我们在工程/业务架构 , 研发工具 , 编译系统等方向深耕 , 支撑业务快速迭代的同时 , 保证超大规模团队的研发效能和工程质量 。在性能/稳定性等方面不断探索 , 努力为全球数亿用户提供最极致的基础体验 。
如果你对技术充满热情 , 欢迎加入抖音基础技术团队 , 让我们共建亿级全球化 App 。目前我们在上海、北京、杭州、深圳均有招聘需求 , 内推可以联系邮箱:tech@bytedance.com ;邮件标题:姓名 - 工作年限 - 抖音 - 基础技术 - iOS/Android 。
【抖音品质建设 - iOS启动优化《原理篇》】
推荐阅读
- 抖音外卖平台代理 抖音外卖可以代理吗
- 碧螺春是什么样子的,碧螺春的品质等级
- 安吉白茶鸭的制作方法,安吉白茶的品质特点
- 白牡丹的感官品质,白茶三个等级
- 碧螺春茶的八大功能,碧螺春的品质等级
- 白茶品质评审步骤,天目湖白茶泡水颜色
- 白茶的加工过程是什么,安吉白茶的品质特点
- 冰岛茶的产地与品质,冰岛普洱茶的茶香
- 数据中台建设从数据中台的认知开始
- 曼糯古树茶品质怎么样,曼糯古树赏析
