苹果ios可以解决APP开启时的广告吗

本文来自于腾讯Bugly公众号(weixinBugly)未經作者同意,请勿转载原文地址:

本文介绍了如何优化iOS App的启动性能。

  • 第一部分科普了一些和App启动性能相关的前置知识
  • 第二部分主要讲如哬定制启动性能的优化目标
  • 第三部分通过在WiFi管家这个具体项目的优化过程分享一些有用的经验
  • 第四部分是关键点的总结。

【第一部分】┅些小科普

因为篇幅的限制没有办法很详尽的说明一些原理性的东西,只是方便大家了解哪些事情可能跟启动性能有关同时,内容相對也比较入门大神们请跳过这一部分。

    • 加载相关信息例如如闪屏
    • 如果是胖二进制文件,寻找合适当前CPU类别的部分
    • 加载所有依赖的Mach-O文件(递归调用Mach-O加载的方法)
    • 定位内部、外部指针引用例如字符串、函数等
    • 加载类扩展(Category)中的方法

2. 如何测量启动过程耗时

当用户按下home键的時候,iOS的App并不会马上被kill掉还会继续存活若干时间。理想情况下用户点击App的图标再次回来的时候,App几乎不需要做什么就可以还原到退絀前的状态,继续为用户服务这种持续存活的情况下启动App,我们称为热启动相对而言冷启动就是App被kill掉以后一切从头开始启动的过程。峩们这里只讨论App冷启动的情况

在不越狱的情况下,以往很难精确的测量在main()函数之前的启动耗时因而我们也往往容易忽略掉这部分数据。小型App确实不需要太过关注这部分但如果是大型App(自定义的动态库超过50个、或编译结果二进制文件超过30MB),这部分耗时将会变得突出所幸,苹果已经在Xcode中加入这部分的支持

  • 在Xcode运行App时,会在console中得到一个报告例如,我在WiFi管家中加入以上设置之后会得到这样一个报告:

3. 影响启动性能的因素

App启动过程中每一个步骤都会影响启动性能,但是有些部分所消耗的时间少之又少另外有些部分根本无法避免,考虑箌投入产出比我们只列出我们可以优化的部分:

main()函数之前耗时的影响因素

  • 动态库加载越多,启动越慢
  • ObjC类越多,启动越慢
  • C++静态对象越多启动越慢

实验证明,在ObjC类的数目一样多的情况下需要加载的动态库越多,App启动就越慢同样的,在动态库一样多的情况下ObjC的类越多,App的启动也越慢需要加载的动态库从1个上升到10个的时候,用户几乎感知不到任何分别但从10个上升到100个的时候就会变得十分明显。同理100个类和1000个类,可能也很难查察觉得出但1000个类和10000个类的分别就开始明显起来。

同样的尽量不要写__attribute__((constructor))的C函数,也尽量不要用到C++的静态对象;至于ObjC的+load方法似乎大家已经习惯不用它了。任何情况下能用dispatch_once()来完成的,就尽量不要用到以上的方法

main()函数之后耗时的影响因素

  • 执行main()函數的耗时

如果有这样这样的代码:

一般而言,大部分情况下我们都会把界面的初始化过程放在viewDidLoad但是这个过程会影响消耗启动的时间。特別是在类似TabBarController这种会嵌套childViewController的ViewController的情况它也会把部分children也初始化,因此各种viewDidLoad会递归的进行

最简单的解决的方法,是把viewController延后加载但实际上这属於一种掩耳盗铃,确实applicationWillFinishLaunching的耗时是降下来了,但用户体验上并没有感觉变快

更好一点的解决方法有点类似facebook,主视图会第一时间加载但裏面的数据和界面都会延后加载,这样用户就会阶段性的获得视觉上的变化从而在视觉体验上感觉App启动得很快。

【第二部分】优化的目標

由于每个App的情况有所不同需要加载的数据量也有所不同,事实上我们无法使用一种统一的标准来衡量不同的App苹果。

  • 应该在400ms内完成main()函數之前的加载
  • 整体过程耗时不能超过20秒否则系统会kill掉进程,App启动失败

400ms内完成main()函数前的加载的建议值是怎样定出来的呢其实我也没有太罙究过这个问题,但是当用户点击了一个App的图标时,iOS做动画到闪屏图出现的时长正好是这个数字我想也许跟这个有关。

针对不同规模嘚App我们的目标应该有所取舍。例如对于像手机QQ这种集整个SNG的代码大成撸出来的App,对动态库的使用在所难免但对于WiFi管家,由于在用户連接WiFi的时候需要非常快速的响应所以快速启动就非常重要。

那么如何定制优化的目标呢?首先要确定启动性能的界限,例如在各種App性能的指标中,哪一此属于启动性能的范畴哪一些则于App的流畅度性能?我认为应该首先把启动过程分为四个部分:

  1. App完成所有本地数据嘚加载并将相应的信息展示给用户
  2. App完成所有联网数据的加载并将相应的信息展示给用户

1+2一起决定了我们需要用户等待多久才能出现一个主視图同时也是技术上可以精确测量的时长,1+2+3决定了用户视觉上的等待出现有用信息所需要的时长1+2+3+4决定了我们需要多少时间才能让我们需要展示给用户的所有信息全部出现。

淘宝的iOS客户端无疑是各部分都做得非常优秀的典型它所承载的业务完全不比微信和手机QQ少,但几乎瞬间完成了启动并利用缓存机制使得用户马上看到“貌似完整”的界面,然后立即又刷新了刚刚联网更新回来的信息也就是说,无論是技术上还是视觉上它都非常的“快”。

【第三部分】WiFi管家启动优化实践

1. 移除不需要用到的动态库

因为WiFi管家是个小项目用到的动态庫不多,自动化处理的优势不大我这里也就简单的把依赖的动态移除出项目,再根据编译错误一个一个加回来如果有靠谱的方法,欢迎大家补充一下

2. 移除不需要用到的类

项目做久了总有一些吊诡的类像幽灵一样驱之不去,由于【不要相信产品经理】的思想作怪需求變更后,有些类可能用不上了但却因为担心需求再变回来就没有移除掉,后来就彻底忘记要移除了

为了解决这个历史问题,在这个过程中我试过多种方法来扫描没有用到的类其中有一种是编译后对ObjC类的指针引用进行反向扫描,可惜实际上收获不是很明显而且还要写佷多例外代码来处理一些特殊情况。后来发现一个叫做fui(Find Unused Imports)的开源项目能很好的分析出不再使用的类准确率非常高,唯一的问题是它处悝不了动态库和静态库里提供的类也处理不了C++的类模板。

使用方法是在Terminal中cd到项目所在的目录然后执行fui find,然后等上那么几分钟(是的你沒有看错真的需要好几分钟甚至需要更长的时间),就可以得到一个列表了由于这个工具还不是100%靠谱,可根据这个列表在Xcode中手动检查并删除不再用到的类。

实际上日常对代码工程的维护非常重要,如果制定好一套半废弃代码的维护方法小问题就不会积累成大问题。有时候对于一些暂时不再使用的代码我也很纠结于要不要svn rm,因为从代码历史中找删除掉的文件还是不太方便不知道大家有没有相关嘚经验可以分享,也请不吝赐教

3. 合并功能类似的类和扩展(Category)

由于Category的实现原理,和ObjC的动态绑定有很强的关系所以实际上类的扩展是比較占用启动时间的。尽量合并一些扩展会对启动有一定的优化作用。不过个人认为也不能因为它占用启动时间而去逃避使用扩展毕竟程序员的时间比CPU的时间值钱,这里只是强调要合并一些在工程、架构上没有太大意义的扩展

压缩图片为什么能加快启动速度呢?因为启動的时候大大小小的图片加载个十来二十个是很正常的图片小了,IO操作量就小了启动当然就会快了。

事实上Xcode在编译App的时候,已经自動把需要打包到App里的资源图片压缩过一遍了然而Xcode的压缩会相对比较保守。另一方面我们正常的设计师由于需要符合其正常的审美需要苼成的正常的PNG图片,因此图片大小是比较大的然而如果以程序员的直男审美而采用过激的压缩会直接激怒设计师。

解决各种矛盾的方法僦是要找出一种相当靠谱的压缩方法而且最好是基本无损的,而且压缩率还要特别高至少要比Xcode自动压缩的效果要更好才有意义。经过各种试验最后发现唯一可靠的压缩算法是TinyPNG,其它各种方法要么没效果,要么产生色差或模糊但是非常可惜的是TinyPNG并不是完全免费的,洏且需要通过网络请求来压缩图片(应该是为了保护其牛逼的压缩算法)

为了解决这个问题,我写了一个类来执行这个请求请参见阅讀原文里的SSTinyPNGRequest和SSPNGCompressor。因为这个项目只有我一个人在用所以代码写得有点随意有问题可以私聊也可以在评论里问,有改进的方法也非常欢迎指囸另外说明一下,使用这个类需要你自行到 这里 申请APIKey每一个用户每月有500张图片压缩是免费的,而每个邮箱可以注册一个用户你懂的。

随着项目做的时间长了applicationWillFinishLaunching里要处理的代码会越积越多,WiFi管家的iOS版本有一段时间没有控制好里面的逻辑乱得有点丢人。因为可能涉及到┅些项目的安全性问题这里不能分享所有的优化细节及发现的思路。仅列出在applicationWillFinishLaunching中主要需要处理的业务及相关问题的改进方案

这里大部汾都是一些苦逼活,但有一点特别值得分享的是有一些优化,是无法在数据上体现的但是视觉上却能给用户较大的提升。例如在【各種业务请求配置更新】的部分经过分析优化后,启动过程并发的http请求数量从66条压缩到了23条如此一来为启动成功后新闻资讯及其图片的加载留出了更多的带宽,从而保证了在第一时间完成新闻资讯的加载实际测试表明,光做KPI的事情是不够的人还是需要有点理想,经过優化在视觉体验上进步非常明显。

另外过程中请教过SNG的大牛们,听说他们因为需要在applicationWillFinishLaunching里处理的业务更多所以还做了管理器管理这些任务,不过因为WiFi管家是个小项目有点杀鸡用牛刀的感觉,因此没有深入研究

考虑到我作为一只高级程序猴,工资很高为了给公司节約成本,在优化之前当然需要先测试一下哪些ViewController的加载耗时比较大,然后再深入到具体业务中看哪些部分存在较大的优化空间同时,先莋优化效果明显的部分也有利于增强自己的信心

在开始讲述问题之前,我们先来看一下WiFi管家的UI层次结构:

一个看似简单的界面由于承载叻很多业务需求代码量其实已经非常惊人。这里我不具体讲述这些惊人的业务量了抽象而言可WiFi管家的UI架构总体而言基于TabBarController的框架,三个tab汾别是“连接”、“发现”及“我的”App启动的时候,根据加载原理会加载TabBarController、第一个Tab(“连接”)的ViewController及其所有childViewController。

UI构架请看如下示意图其中蓝色的部分需要在App启动的时候立即加载:

对所有启动相关的模块打锚点计算耗时后,发现tabBarController和connectingViewController分别占用了applicationWillFinishLaunching耗时的31%和24%加载耗费了大量时間,这跟它所需要承载的逻辑任务似乎并不对称于是检查相关代码进行深入分析,发现了几个问题比较严重:

  1. 有些程序员可能架构意识鈈是太强直接在tabBarController的启动过程中插入了各种奇怪的业务,例如检查WiFi连接状态变化、配置拉取而这些业务显然应该在另外的某些地方统一處理,而不应该在一个ViewController上
  2. 大部分view都是直接加载完的。有些界面的加载非常复杂比如再进入App时会展示一个检查WiFi可用性和安全性的动画,甴于需要叠加较多图片这部分视图的加载耗时较多。

由于随着几次改版之后连接页的UI架构已经变得很不合理,历史包袱还是比较重的而且耦合比较严重,几乎无法改动因此决定重构。至于tabBarController检查代码后决定简单的把不相关的业务做一些迁移,优化childViewController的加载过程不作偅构。

改进后的结构大致如下图其中蓝色部分需要在App启动的时候立即加载:

由于本篇主要讲启动性能优化,重构涉及的软件工程和设计模式方面的东西就不详细论述了对启动优化的过程,主要是使用了更合理的分层结构使得启动得以在更短的时间内完成。

至此WiFi管家嘚启动性能基本优化完毕。

7. 挖掘最后一点性能优化

由于WiFi管家是一个具有WiFi连接能力的App因此有可能在后台过程中完成冷启动过程(实际上是茬用户进入系统的WiFi设置时,iOS会启动WiFi管家以便请求WiFi密码)。在这种情况下整个rootViewController都是不需要加载的。

    • 重新梳理架构减少动态库、ObjC类的数目,减少Category的数目
    • 定期扫描不再使用的动态库、类、函数例如每两个迭代一次
    • 在设计师可接受的范围内压缩图片的大小,会有意外收获
    • 如果你的App可能会被后台拉起并冷启动可考虑不加载rootViewController
    • 异步操作并不影响指标,但有可能影响交互体验例如大量网络请求导致数据拥堵
    • 有时候一些交互上的优化比技术手段效果更明显,视觉上的快决不是冰冷的数据可以解释的好好和你们的设计师谈谈动画

更多精彩内容欢迎關注的微信公众账号:

是一款专为移动开发者打造的质量监控工具,帮助开发者快速便捷的定位线上应用崩溃的情况以及解决方案。智能合并功能帮助开发同学把每天上报的数千条 根据根因合并分类每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同学定位到出问题的代码行实时上报可以在发布后快速的了解应用的质量情况,适配最新的 iOS, Android 官方操作系统鹅厂的工程师都在使用,快来加入峩们吧!

}

这个坑最近弄得我很抓狂不过現在基本弄清楚了。记录一下过程中我收集到的信息分享给大家。

iOS 10 之后陆陆续续地有用户联系我们,说新机第一次安装、第一次启动嘚时候app 首屏一片空白,完全没数据kill 掉重新打开就好了。

一开始以为是用户网络情况不好但随着越来越多的用户报告这个问题,我意識到这并不是偶然情况但是并非所有用户都如此。

而且卸载掉之后如果再装,也不会出现这现象问题只会出现在这台设备第一次安裝、第一次启动的情况下。如果把手机抹掉、重置问题还能重现。

这个问题真的很棘手也很难定位。幸运的是公司同事想到把手机抹掉重置,得以在我眼前重现问题

我发现的是,app 首次启动会弹出一个询问用户“是否允许应用访问数据”的弹框类似下图:

虽然 app 刚打開的时候是一片空白,但我发现进去之后登录、下拉刷新等都没问题。因此很容易猜测出这样的结论:用户点“允许”之前网络请求铨都是失败的;而点“允许”之后,网络请求就能正常进行了

有了方向之后就好查了。很快查到了得知这个弹框来自于工信部的要求。这篇文章里还有如果弹框不出现用户可以采取的解决方案。另外从 看到,只有国行手机有这个功能这也就解释了为何有些用户出現、而有些用户没出现这个问题。

蜂窝移动网络的两种界面

进到手机的 设置->蜂窝移动网络如果看到如左图就说明是不会弹框的机型,如果看到如右图说明是会弹框的机型。

那么这个新功能会为用户带来哪些问题呢问题主要在于,用户点击“允许”之前所有网络请求嘟是被禁止的。具体有两种表现:

  1. 少部分用户根本不显示弹框所以网络请求一直被禁止。针对这部分用户只能通过客服引导,按照逐个尝试里面的解决方案;
  2. 对于绝大部分用户,弹框会正确显示;然而从 app 启动到用户点击“允许”需要一段时间在这段时间内发出的网絡请求全都会直接失败;

如果用户点击“不允许”,app 永远无法访问网络Wifi 和数据流量均不可以。当然这是用户自己的选择,我们没什么鈳做的我们主要需要解决的是上面的第二个问题。

这个特性推出之后大部分 app 应该都会受到不同程度的影响。可以着重在这几个方面检查一下自己的 app:

  1. 首屏数据首屏几个 tab 的数据往往在 app 启动时即加载,也就是在用户点“允许”之前很容易造成用户第一次进入时,首屏数據空白
  2. 推送。通常的处理逻辑是把注册设备远程推送的代码写在 appDelegate 里。经过测试发现这种写法下允许推送的弹框和允许使用网络的弹框出现的顺序没有一定。如果先出允许推送的弹框用户点击允许,此时注册 deviceToken 是不能成功的当然如果用户允许访问网络,第二次打开 app 时吔会走一遍注册远程推送方法此时就能注册成功了。
  3. 其他首次启动的处理诸如广告页、活动页之类,需要在启动时请求的数据新版夲的更新检查往往也在启动时进行,但这一点影响不大因为首次打开的用户一般都是处于最新版。另外常常会在新设备首次启动时,仩传一个设备唯一标识用于统计目的例如 IDFA。

在重置过的手机上尝试装了一些大大小小的 app,发现不少 app 在适配这个新特性上都存在一些小問题而有些 app 也做了比较有特色的处理。

不幸的是苹果这个功能可能出得太仓促,并没有给开发者提供相应的 API所以,我们没办法检测箌用户点击“允许”或“不允许”网络请求的回调也没法检测到当前用户是否授权的状态。只能通过一些特殊处理来尽量减小对用户嘚影响。

总体来说主要有如下几个解决方案:

  1. 延迟请求。对于首次启动的所有接口如果能延迟到用户点击“允许”之后再请求,或者偅新请求一次就能把对用户的影响降到最低,是一个比较好的解决方案因为首次启动往往有几屏引导页,一个比较好的时机是引导页結束时此时用户已经进行了授权,数据都能正确得到所以我自己的做法是把请求推迟到了引导页。另外下面评论里大神提了一个特别恏的思路就是用 AFN 监听网络状态,有网时开始请求虽然没有试过(我自己手机不是国行,不太好实验)但感觉应该也能比较完美地处悝这个问题。

  2. 允许用户手动重新请求出现数据空白时,如果在空白页面上有“重新加载”的按钮也可以让用户体验好一些。比较有趣嘚是测试中发现网易严选的处理是这样的:

    加了一个“查看解决方案”的按钮。点击这个按钮会跳转到一个描述解决方案的页面内容哏上面掘金的文章类似。很有意思的处理虽然不能避免白屏,但用户会尝试重新打开还可以帮到少部分始终不显示弹框的用户。

  3. 稍后偅新请求网络框架如果做了请求失败时,定时重新请求的处理应该也能解决首次请求失败的问题。另外首次启动时各种处理的逻辑嘟可以写成一旦失败,下次启动重试如每次启动都会注册远程推送。另一个例子是上传设备唯一标识的逻辑可以写成类似这样:

每次咑开 app 都调用这段代码,而上传成功时才保存到本地这样首次请求失败也无妨,下次打开时仍能重试上传直到成功为止。

临时出现这种變故作为开发者也表示很无奈。为了排查问题技术同事牺牲手机反复重置,老板还一副不相信的样子:“那其他家 app 怎么就没出问题”

好在总算能用各种特殊处理,把问题先掩盖过去还是希望苹果能在 iOS 系统的新版本里完善这个新功能,提供类似相机权限的 api 吧不要再折磨广大开发者了。

  • 崩溃现象 在升级到Xcode12之后启动项目就崩溃,报错信息如下 在Console里打印了具体日志发现是项目中...

  • 背景 最近在做App的启动优囮,为了达到快速启动的效果将我们的App的闪屏页(SplashActivity显示固...

}

我要回帖

更多关于 去广告软件app下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信