iOS App性能优化

 

虽然iPhone的机能越来越好,但是app的功能也越来越复杂,性能从来都是移动开发的核心关注点之一。我们说一个app性能好,不是简单指感觉运行速 度快,而应该是指应用启动快速、UI反馈响应及时、列表滚动操作流畅、内存使用合理,当然更不能随随便便Crash啦。工程师开发应用时除了在设计上要避 免性能“坑”的出现,在实际遇到“坑”时也要能很快定位原因所在。定位性能问题原因当然不能靠猜,合理的方法是使用工具测量评估出投资回报最高的问题点, 然后再加以优化。

 

启动时间

 Resume 10秒 Suspend 10秒 Quit 6秒Background Task 10分钟

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

application:didFinishLaunchingWithOptions中添加:

dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@”Lauched in %f seconds.”,  (CFAbsoluteTimeGetCurrent() – StartTime)); 
});可能你会觉得为什么这样可拿到系统启动的时间,因为这个dispatch_async中提交的工作会在app主线程启动后的下一个run lopp中运行,此时app已经完成了载入并且将要显示第一帧画面,也就是系统会运行到`-[UIApplication _reportAppLaunchFinished]`之前。下图是用Instruments工具Time Profiler跑的调用栈,Instruments的使用方法建议看WWDC中与performance相关的[session录像](https://developer.apple.com/videos/wwdc),文字写起来太单薄不够直观哈。

[UIApplication _reportAppLaunchFinished]之前完成了系统回调application:didFinishLaunchingWithOptions

WWDC 2012 Session 235):

2)UIKit初始化:如果应用的Root View Controller是由XIB实现的,也会在启动时被初始化。

application:didFinishLaunchingWithOptions

-[UIApplication _resportAppLaunchFinished]中调用CA::Transaction::commit实现第一帧画面的绘制。如果你的程序启动很慢,能 做的首先是将与显示第一屏画面无关的操作放到之后执行;如果是用XIB文件load第一屏,XIB文件中的View层也要如果扁平,不要有太多图层。

如何能够让用户觉得你的app响应迅速呢?当然是app用户所触发的操作都能得到立刻响应,即用户事件(User Event)能够被主线程的run loop及时处理。什么是run loop?可以想象成一个处理事件的select多路复用。主线程中的run loop当然主要是为了处理用户产生的事件啦,例如点击、滚动等。以后我们会详细聊聊run loop这个让人迷惑的东东。

 

内存问题从来都是iOS app的老大难问题,搞不好程序就爆了。由于iOS系统没有Swap文件(知道为啥不?留给悬念),在内存不足时会将只读数据(例如code page)从内存中移出,需要的时候再从disk上读如内存;可读写数据不会被系统从内存中移出,然而如果占用的内存达到一个阈值,系统会发出相应的通知 和回调让应用release对象以回收内存,如果仍然不能减少内存使用量,系统会直接关闭应用。尤其是iOS 5.0之后,如果你的app收到了memory warning,那么脑袋也是和其他app一样放在了案板上,随时有可能被kill掉,并不是说一定会先Kill掉在后台的app。

 

+[NSobject alloc]/malloc),还会有更多使用内存的地方,比如代码和全局数据(TEXT和DATA),线程栈,图片,view 的layer backing store等等。因此处理内存问题,绝不仅仅是我们开发app时尽量少申请内存那么简单。

另一种严重的内存使用问题是引用了已经释放的内存,直接导致应用崩溃,而Allocation有一个选项Enable NSZombie detection能够在应用使用已经释放的内存时标注出来,同时显示错误发生的调用栈信息。这为解决问题提供了最直接的帮助,当然缺点是必须能够重现 EXEC_BAD_ACCESS错误。

图形性能对用户体验有直接的影响,Instruments中的Core Animation工具用于测量物理机上的图形性能,通过视图的刷新频率大小来判断应用的图形性能。例如一个复杂的列表滚动时它的刷新率应该努力趋近于 60fps才能让用户觉得够流畅,从这个数字也可以算出run loop最长的响应时间应该是16毫秒。

Instruments可以在物理机上显示出被混合的图层Blended Layer(用红色标注),Blended Layer是因为这些Layer是透明的(Transparent),系统在渲染这些view时需要将该view和下层view混合(Blend)后才能 计算出该像素点的实际颜色,如果这种blended layer很多,那么在滚动列表时就甭想有流畅的效果。

[UIColor clearColor],要知道背景颜色为clear color那可是图形性能的大敌,基本意味着blended layer是跑不了的了,为什么?自己思考一下:)

很多视图Layer由于Shadow、Mask和Gradient等原因渲染很高,因此UIKit提供了API用于缓存这些Layer:[layer setShouldRasterize:YES],系统会将这些Layer缓存成Bitmap位图供渲染使用,如果失效时便丢弃这些Bitmap重新生 成。图层Rasterization栅格化好处是对刷新率影响较小,坏处是删格化处理后的Bitmap缓存需要占用内存,而且当图层需要缩放时,要对删格 化后的Bitmap做额外计算。 使用这个选项后时,如果Rasterized的Layer失效,便会标注为红色,如果有效标注为绿色。当测试的应用频繁闪现出红色标注图层时,表明对图层 做的Rasterization作用不大。

Misaligned Image表示要绘制的点无法直接映射到频幕上的像素点,此时系统需要对相邻的像素点做anti-aliasing反锯齿计算,增加了图形负担,通常这种问题出在对某些View的Frame重新计算和设置时产生的。

(4) Color Offscreen-Rendered Yellow

大部分Offscreen-Rendering都是和视图Layer的Shadow和Mask相关,下列情况会导致视图的Offscreen- Rendering: 1. 使用Core Graphics (CG开头的类)。 2. 使用drawRect()方法,即使为空。 3. 将CALayer的属性shouldRasterize设置为YES。 4. 使用了CALayer的setMasksToBounds(masks)和setShadow*(shadow)方法。 5. 在屏幕上直接显示文字,包括Core Text。 6. 设置UIViewGroupOpacity。

Designing for iOS: Graphics & Performance对 offsreen以及图形性能有个很棒的介绍,(5) Color Copied Images Copied Image选项可以标注应用绘制时被Core Animation复制的图片,标注成蓝绿色。虽然我在运行时遇到过,不过个人感觉对图形性能影响不大。 (6) Color Immediately,Flash Updated Regions, Color OpenGL Fast Path Blue Color Immediately选项表示Instruments在做color-flush操作时取消10毫秒的延时。Flash Updated Regions选项用于用红色示标示出在屏幕上使用GPU计算绘制的图层。Color OpenGL Fast Path Blue选项用于用蓝色标示出在屏幕上由OpenGL compositor绘制的内容。 这三个选项对图形性能的分析意义较小,通常仅作为参考。

如果需要对app的文件和网络I/O情况做分析,可以用到这三个Instruments工具System Usage、File Activity和Network。

 

工具File Activity只能在模拟器中运行,因此数据采集可能不是非常准确。它同样可以详细给出读取的文件属性、大小、载入时间等信息,适合与System Usage配合使用。

涉及iOS App性能的知识很多,上面只是冰山一角,重点推荐WWDC的session。

 

 

  • 406: Adopting Automatic Reference Counting
  • 238: iOS App Performance: Graphics and Animations
  • 242: iOS App Performance: Memory
  • 235: iOS App Performance: Responsiveness
  • 409: Learning Instruments
  • 706: Networking Best Practices
  • 514: OpenGL ES Tools and Techniques
  • 506: Optimizing 2D Graphics and Animation Performance
  • 601: Optimizing Web Content in UIWebViews and Websites on iOS
  • 225: Up and Running: Making a Great Impression with Every Launch

 

  • 105: Polishing Your App: Tips and tricks to improve the responsiveness and performance
  • 121: Understanding UIKit Rendering
  • 131 performance optimization on iphone os
  • 308: Blocks and Grand Central Dispatch in Practice
  • 323: Introducing Automatic Reference Counting
  • 312: iOS Performance and Power Optimization with Instruments

http://oleb.net/blog/2011/11/ios5-tech-talk-michael-jurewitz-on-performance-measurement/

http://robots.thoughtbot.com/post/36591648724/designing-for-ios-graphics-performance

http://www.touchwonders.com/en/how-to-make-your-apps-feel-responsive-and-fast-part-2/

posted on 2015-08-18 16:35  奋进的闹钟  阅读(259)  评论(0编辑  收藏  举报

导航