美文网首页aa雨下思考#iOS#HeminWon
iOS App性能优化之启动时间、内存

iOS App性能优化之启动时间、内存

作者: SuperZico | 来源:发表于2016-06-16 15:11 被阅读3659次

最近在忙着优化之前的app,客户反映启动的有点慢,深层次页面加载会有卡顿的情况,乘着现在有些空闲在这里做一个小记录
虽然iPhone的机能越来越好,但是app的功能也越来越复杂,性能从来都是移动开发的核心关注点之一。我们说一个app性能好,不是简单指感觉运行速度快,而应该是指应用启动快速、UI反馈响应及时、列表滚动操作流畅、内存使用合理,当然更不能随随便便Crash啦。工程师开发应用时除了在设计上要避免性能“坑”的出现,在实际遇到“坑”时也要能很快定位原因所在。定位性能问题原因当然不能靠猜,合理的方法是使用工具测量评估出投资回报最高的问题点,然后再加以优化。
1.启动时间
应用启动时间长短对用户第一次体验至关重要,同时系统对应用的启动、恢复等状态的运行时间也有严格的要求,在应用超时的情况下系统会直接关闭应用,要获取准确的app启动所需时间,最简单的方法时首先在main.c中添加如下代码:

CFAbsoluteTime StartTime;
int main(int argc, char **argv) {
StartTime = CFAbsoluteTimeGetCurrent();

然后在AppDelegate的回调方法application:didFinishLaunchingWithOptions中添加:

dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@”Lauched in %f seconds.”, (CFAbsoluteTimeGetCurrent() – StartTime));
});

App的启动会包括以下几个部分(来自WWDC 2012 Session 235):
1)链接和载入:可以在Time Profile中显示dyld载入库函数,库会被映射到地址空间,同时完成绑定以及静态初始化。
2)UIKit初始化:如果应用的Root View Controller是由XIB实现的,也会在启动时被初始化。
3)应用回调:调用UIApplicationDeleagte的回调:application:didFinishLaunchingWithOptions
4)第一次Core Animation调用:在启动后的方法-[UIApplication _resportAppLaunchFinished]中调用CA::Transaction::commit实现第一帧画面的绘制。
基本上减少启动时间就是在这些方面下一些功夫,如果你的程序启动很慢,能 做的首先是将与显示第一屏画面无关的操作放到之后执行;如果是用XIB文件load第一屏,XIB文件中的View层也要如果扁平,不要有太多图层。比较反面的案例就是最近发现的斗鱼直播app,首页的数据居然是在启动载入页时完成的,网络卡顿时长时间停留在启动页,客户体验太差了

2.内存问题
内存问题从来都是iOS app的老大难问题,搞不好程序就爆了。由于iOS系统没有Swap文件(知道为啥不?留给悬念),在内存不足时会将只读数据(例如code page)从内存中移出,需要的时候再从disk上读如内存;可读写数据不会被系统从内存中移出,然而如果占用的内存达到一个阈值,系统会发出相应的通知和回调让应用release对象。在ARC之后,内存问题相对少了很多,但是也会莫名其妙的出现内存的问题,我推荐大家调试的时候讲xcode切换到手机性能查看页看一下内存的使用情况,有些死循环是内存慢慢增加的,一般测试很难测试出来。如果需要获取更详细的内存动态,Allocations工具可以很直观的反应app的内存使用情况。

3.文件和网络I/O
如果需要对app的文件和网络I/O情况做分析,可以用到这三个Instruments工具System Usage、File Activity和Network。
工具System Usage可以统计出运行状态下应用的文件和网络IO操作数据。例如我们发现应用启动后又一个峰值,这可能存在问题,我们可以利用System Usage工具的详细信息栏查看应用是由于对哪些文件的读写操作导致了峰值,一般这里很容易出现页面载入卡顿
工具File Activity只能在模拟器中运行,因此数据采集可能不是非常准确。它同样可以详细给出读取的文件属性、大小、载入时间等信息,适合与System Usage配合使用。

Network工具则可以采集到应用的TCP/IP和UDP的使用信息(传输的数据量、当前所有TCP连接等),用得不多,做网络使用状况分析时用用还行。

相关文章

网友评论

  • 天口三水羊:我主要关心 启动时间是怎么计算的 如何统计,求解
    SuperZico:本文的方法计算的是从启动到程序第一帧绘制需要的时间,不包含网络,内存数据读取等其他不可控的时间计算,所以用的是OpenGL ES的UI绘制计算时间公式,给个ep:
    //START:link
    - (BOOL)link

    {

    CFAbsoluteTimestartTime =CFAbsoluteTimeGetCurrent();

    GLintstatus;

    glLinkProgram(program);

    glGetProgramiv(program,GL_LINK_STATUS, &status);

    if(status ==GL_FALSE)

    returnNO;

    if(vertShader)

    {

    glDeleteShader(vertShader);

    vertShader=0;

    }

    if(fragShader)

    {

    glDeleteShader(fragShader);

    fragShader=0;

    }

    CFAbsoluteTimelinkTime = (CFAbsoluteTimeGetCurrent() - startTime);

    NSLog(@"Linked in %f ms", linkTime *1000.0);

    returnYES;

    }
  • 2018火:StartTime 变量如何在appdelegate里面找到 ?
    2018火:@HelloZico 谢谢,一直没怎么使用这个关键字都忘记了。
    SuperZico:@腕理路 在 AppDelegate.m 的开头声明 extern CFAbsoluteTime StartTime; 因为是写给自己看的,以为我写的东西没人看偷懒没写--
  • b59457960ac9:最近也在着手这块,启动时间那块可以细说下怎么优化启动时间吗?把第三方初始化放到子线程感觉不起作用
    SuperZico:@Twistar 启动时间计算的是从程序响应到绘取第一帧的时间,我查到的资料列出的四点里没有设计到线程,第三方初始化推荐使用懒加载

本文标题:iOS App性能优化之启动时间、内存

本文链接:https://www.haomeiwen.com/subject/nummdttx.html