iOS启动优化

数字先锋说
• 阅读 2076

启动速度优化背景:

我们的项目在项目为一个开发迭代多年的老项目,之前对项目的启动性能没有太多的关注,导致APP的启动速度比较慢,启动有时要耗时3、4s钟,整体启动性能堪忧。我们主管安排我负责优化,全力优化APP启动速度。

遇到挑战:

最大挑战有2个,一是代码历史代码性能消耗没有把控,很多地方存在不合理的代码;二是做为入职不久的新人需要在1个月完成左右优化,时间紧任务重;

优化步骤:

首先我们梳理好目标,iOS启动可以分为冷启动和热启动。冷启动是指APP本身不在后台系统,从用户点击应用icon到appDelegate didFinishLaunching方法执行完成用户看到APP首页为止;热启动是APP本身在系统后台运行,从后到点击到进入APP场景。我们重点是优化冷启动的速度,启动速度时间目标由3s降到1.2s;
有了明确目标后接下来是对目标进行拆解,要进行冷启动优化我们需要知道冷启动过程具体做了什么,具体哪部分执行节点耗时较多。APP冷启动可以大概分为三个阶段,第一阶段是main函数之前,系统执行一系列加载和链接工作;第二阶段是main函数之后,从main函数开始到AppDelegate的didFinishLaunchingWithOptions执行完毕;第三阶段是从didFinishLaunchingWithOptions执行到APP渲染出APP的首页;我们需要从这三个阶段来进行优化,首先我们需要分析这三个阶段的耗时情况。
测算main函数之前的耗时,我们可以通过配置xcode来进行,在xcode的editScheme中Run→ Environment Variables 添加name为DYLD_PRINT_STATISTICS为1,这样就可以在xcode控制台中一份输出报告示例如下:

从上图中我们可以清晰了解main函数前的耗时,以及过程中加载动态库耗时、oc类初始化耗时、指针重定义耗时。对于main函数后我们可以通过加入计时代码来统计,这块统计比较简单;

main函数前核心优化:主要包括优化动态加载库、Rebase/Binding优化和优化初始化阶段

动态库加载优化:
我们主要进行2方面的优化,
1.消灭内嵌的动态库,因为系统加载内嵌动态库会消耗比较大的性能;
2.减少动态库的数量,可以通过合并已有的动态库来达到目的,动态库越多性能开销越多;

Rebase/Binding优化:
主要进行了2类优化,
1.减少oc类、减少方法、减少分类数量;
2.使用Swift structs可以大幅减少符号数量;

Initializers阶段优化:最核心是减少load方法使用,load执行代码越多启动会越慢,我们可以把load的实现代码延迟放到initiailize方法中,在initiailize方法不会影响APP的启动速度;

main函数后阶段优化:这个阶段核心优化思路是减少主线程的性能消耗,对于基础组件的初始化做到能延后的延后,能放到子线程初始化的放到子线程初始化。
通过以上优化后我们APP的启动速度有了很大的提升,由原来的3s出头优化到了1.2s左右。

接入总结和建议:整体接入还是比较简单,官网在整体的说明文档方面比较清晰。整个apm在崩溃做的比较好,对比之前用的听云和bugly还是不错的,在信息收集的全面性方面特别好,另外对于崩溃日志解析和准确性方面比较好,崩溃的堆栈相对其他产品更易懂。

对产品的建议:在使用过程中发现以下问题建议参考优化
(1) 从u-apm注册后,在之后的主页就找不到关于u-apm的内容了,注册完后注册了一个APP发现是接入友盟基础SDK,不是我想要的,只能通过返回到活动也才找到u-apm。
(2) 想接入一个没有idfa的版本,没找到,看接入注意是强制收集了idfa,定位和idfa国家对我们这个行业有限制,特别是位置权限不允许用;
(3) 官网上播放视频和下面的介绍叠在一起,无法全屏看(Safari浏览器)
(4) 概览中,崩溃率、ANR描述使用专门名词,现在都使用“错误“统称,并不符合开发的认知,比如崩溃就是崩溃率,anr就说是anr,而不是统称为崩溃;
(5) 实时概览更希望看的是一些总的数据表,比如崩溃Android崩溃希望看java和原生底层加起来的总崩溃,另外建议实时概览增加卡顿率、网络错误率、启动速度等一些关键指标的总览图;二级页面再增加卡顿、崩溃等详情;

作者:盛夏
从事iOS开发5年,做过社交和教育APP研发

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
把帆帆喂饱 把帆帆喂饱
3年前
登陆时间的优化
登陆时间的优化这是一个登陆的请求,在项目启动后首次调用,耗时近800ms,而第二次调用改接口时则只花费了29ms,性能有较大的提升空间。下面针对此问题进行一系列的优化。耗时排查项目启动后清空日志,然后调用接口,发现会创建一个dispatcherServle
kenx kenx
4年前
SpringBoot包扫描之多模块多包名扫描和同类名扫描冲突解决
前言我们在开发springboot项目时候,创建好SpringBoot项目就可以通过启动类直间启动,运行一个web项目,非常方便简单,不像我们之前通过SpringSpringMvc要运行启动一个web项目还需要要配置各种包扫描和tomcat才能启动我将应用分成了parentcommoncomponentapp这种模式,1.parent是一个单纯的p
Wesley13 Wesley13
4年前
RAC环境单实例启动数据库收到ORA
     在RAC环境中,如果你在没有启动节点的集群服务的情况下单实例启动数据库,将收到类似如下的报错:\oracle@rhel1u01\$sqlSQL\Plus:Release10.2.0.5.0ProductiononTueApr215:00:272013Copyright(
九章 九章
4年前
Android应用启动速度优化
应用启动流程总结:①点击启动一个App,Launcher进程采用BinderIPC向ActivityManagerService发起startActivity请求;②ActivityManagerService接收到请求后,向zygote进程发送创建进程的请求;③Zygote进程fork出新的子进程,即App进程;④App进程通过Bin
Stella981 Stella981
4年前
Cmder启动速度优化
为加快cmder启动,我们可以做一些简单优化,减少环境变量检测和批处理调用操作优化前启动时间:1.69秒优化后启动时间:0.53秒1\.将cmder下批处理中lib\_console输出禁用    
Wesley13 Wesley13
4年前
Unity横屏
Android下发现Unity里面的Player设置,并不能完全有效,比如打开了自动旋转,启动的时候还是会横屏,修改XML添加以下代码<applicationandroid:icon"@drawable/ic\_launcher"                    android:label"@string/app\_name"
Stella981 Stella981
4年前
C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
 原创笔记,转载请注明出处!点击【关注】,关注也是一种美德~错误描述:1已启动生成:项目:FirstCode,配置:DebugWin321生成启动时间为2018/2/521:00:30。1InitializeBuildStatus:1 正在
从iOS App启动速度看如何为基础性能保驾护航 | 京东物流技术团队
启动是App给用户的第一印象,一款App的启动速度,不单单是用户体验的事情,往往还决定了它能否获取更多的用户。所以到了一定阶段App的启动优化是必须要做的事情。
陈杨 陈杨
8个月前
鸿蒙5开发宝藏案例分享---冷启动优化案例分享
鸿蒙冷启动优化大揭秘!这些官方宝藏案例让我效率翻倍🚀大家好呀!最近在优化鸿蒙应用时,我偶然发现了官方文档里隐藏的性能优化宝藏案例。这些实战经验让我的应用启动速度直接起飞!今天就把这些干货整理分享给大家,附详细代码解析和避坑指南一、冷启动为何如此重要?当用