APP性能优化汇总

作者: _既白_ | 来源:发表于2017-05-15 16:47 被阅读115次

    简介

    随着IPhone手机市场的快速发展,苹果对 IOS APP的审核和要求也更加的苛刻。所以APP的性能是决定能否上架,能否给用户更好的用户体验的关键因素之一。性能优化主要包括启动速度、UI反馈与响应、列表的滚动流畅性、内存是否泄漏、图形动画、等方面。

    TabViewCell性能分析

    • 重用思想。
      (1)我们不仅要对tableviewcollectionviewcell进行重用,而且还要对两者的HeardViewFooterView进行重用。
      (2)在开发中我们会用到很多重复的视图、模型,比如相似度很高的控件,数据基本类似的model,这时候我们应该考虑如何避免重复创建这些控件和模型,而是利用现有的最少的资源实现想要东西。
      (3)对于与重用标识符我们最好使用关键字Static去修饰重用标识符,确保重用标识符在内存中之内创建一次。
      (4)Views越多就意味着需要渲染的越多,所以消耗性能就越大,所以重用很重要。

    • Cell内容布局和Cell动态行高。对于相对复杂度、计算量比较大的布局,我们可以在Cell内容展示之前通过异步方式将展示内容的Frame、cell的行高,依赖关系提前计算好,并做动态缓存,在展示的时候直接将Frame赋值响应的控件。流程:如果缓存有Frame,直接给控件的frame赋值;如果缓存中没有,在Cell内容展示之前通过异步方式将展示内容的Frame和依赖关系提前计算好,给控件的frame赋值,并缓存好计算的frame

    • 通过instuments中的Core Animation调试。
      (1)图层混合。
      检测界面多个UI控件叠加的情况,对比图层颜色显示,如果显示为红色,说明使用透明或者半透明的控件,致使GPU计算这些这些图层最终的显示的颜色的时候消耗了大量的GPU资源。检测如果显示为绿色说明没有使用透明或者半透明的控件,性能好。
      优化:
      1,设置opaque 属性为true
      2,给View设置一个不透明的颜色,没有特殊需要设置白色即可。
      (2) 图片的颜色格式。
      检测Cell上的内容设置图片的颜色格式,如果GPU不支持当前图片的颜色格式,那么就会将图片交给GPU预先进行格式转化,转化成合适的格式需要消耗大量GPU资源,CoreAnimation会将这张图片标记为蓝色。那么GPU支持什么格式呢?苹果的GPU只解析32bit的颜色格式,如果使用Color Copied Images去调试发现是蓝色,那么就找设计去要张格式合适的图吧···
      (3)图片大小。
      查看图片大小是否正确显示。*如果image sizeimageView size不匹配,image会出现黄色。要尽可能的减少黄色的出现,因为image size与imageView size不匹配,会消耗资源压缩图片。
      (4)离屏渲染。
      离屏渲染(Off-Screen Rendering)指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
      当前屏幕渲染(On-Screen Rendering ),指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。
      离屏渲染的危害,离屏渲染会先在屏幕外创建新缓冲区,离屏渲染结束后,再从离屏切到当前屏幕, 把离屏的渲染结果显示到当前屏幕上,这个上下文切换的过程是非常消耗性能的,实际开发中尽可能避免离屏渲染。
      导致离屏渲染的原因:

    layer.shadow
    layer.allowsGroupOpacity or layer.allowsEdgeAntialiasing
    layer.shouldRasterize
    layer.mask
    layer.masksToBounds && layer.cornerRadius
    

    所以在Cell中尽量避免给控件图层使用shadow(阴影)、shouldRasterize(光栅化)、layer.masksToBounds && layer.cornerRadius(设置圆角)等属性。

    • 图片加载方式。
      (1)异步加载思想。
      加载图片,从内存中查找,如果内存中有数据,则显示图片。如果内存中没有图片,查找本地资源加载到内存,显示图片。如果本地没有数据,异步下载图片,图片下载完成后显示图片,并将图片资源加载到内存和本地。运用这种流程概念能大大优化图片加载,比如SDWebImage框架。
      (2)利用OC运行时机制实现Cell的滑动和加载图片。
      当tableview的cell上有需要从网络获取的图片的时候,滚动tableView,异步线程会去加载图片,加载完成后主线程就会设置cell的图片,但是会造成卡顿。可以让设置图片的任务在CFRunLoopDefaultMode下进行,当滚动tableView的时候,RunLoop是在 UITrackingRunLoopMode 下进行,不去设置图片,而是当停止的时候,再去设置图片。
    -(void)viewDidLoad {
    [super viewDidLoad];
    // 只在NSDefaultRunLoopMode下执行(刷新图片)
    [self.myImageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@""] afterDelay:ti inModes:@[NSDefaultRunLoopMode]];    
    }
    

    (3)本地图片加载:从Bunder中加载图片有两种方式,imageWithNameimageWithContentOfFileimageWithName加载图片的时候会缓存图片到内存,不适合加载太大的图片,不然对消耗大量的内存性能。imageWithContentOfFile仅加载图片不会缓存,适合加载大图片且不会被反复使用的图片,节省内存,提高性能。
    (4)图片颜色格式、图片大小:如CoreAnimation上介绍

    • Cell刷新。
      (1)尽量减少使用reloadData刷新Cell,尽可能使用局部刷新。
      (2)上下拉刷新功能,尽量设置一次刷新接受的数据条数在10条——15条之内,如果接受的数据过多,数据的处理的过程就越长,展示到UI上就非常慢,界面会出现短暂的空白或者很长时间才展示,体验很差。

    • DrawRect方法绘制自定义控件
      单元格中的内容可以在自定义Cell中使用DrawRect方法内自己绘制。

    • Cell高度固定,如果单元格的高度固定,直接使用RowHeight设置高度,性能比在Cell方法中设置高度要好。

    避免使用大量的XIB文件。

    因为一个程序中XIB文件都是动态加载的,在编译的时候就会被全部加载到内存中。如果程序中使用了大量的XIB文件,不仅影响启动程序的速度,而且还占用了大量内存空间,用户的体验大大折扣。

    做任何事都不要阻塞主线程

    苹果将所有关于UI操作的内容都放在主线程(UI线程)中,原因是将所有的UI资源放在一个线程中,而且在主线程中任何属性的生命都是用非原子类型的。
    (1)为了避免资源抢夺的危险;
    (2)为了不用为主线程中的资源枷锁,因为加锁是非常浪费系统资源的。
    (3)主线的优先级最好,放在主线程中的操作执行的更快,响应的更加灵敏,用户体验非常好。
    (4)所以任何关于UI的操作都要放在主线中去操作。而无关UI的操作最好放到子线程中操作,比如上传、下载、网络请求、定时器等耗时操作。

    尽量在ViewWillAppear方法中少写代码。

    因为ViewWillAppear实在视图出现之前执行,如果在这个方法中执行了很多操作,会导致程序启动很慢,影响用户体验。

    集合的选择和使用

    NSSArray:是有序的一组值。用index查询快,但是插入和删除慢。
    NSDictionary:是无序的,通过key存储的,所以通过Key查找很快。
    Sets:无序的一组值,通过Value查找快,删除和插入块。
    所以合理的选择数据封装格式,也更够提高软件性能。

    延迟加载(懒加载)

    懒加载的思想也是很重要,苹果官方封装的UI控件,大部分都利用到了懒加载的思想,比如ViewControllerViewcell上的子视图等。懒加载是在用到的时候才回去加载,这样做不仅避免所用的控件同时添加到内存中,而且还防止了控件的重复创建。

    声明对象时尽量避免使用New关键字,多使用init alloc.

    因为使用init alloc系统会默认调用initWithZone方法分配内存空间,分配的原则是类型相近就近分配,而New只是简单初始化,内存分配随机,所以使用init alloc声明对象减少了系统寻找堆中对象浪费的资源。

    缓存思想。

    要想提高软件性能,开发过程中做好缓存至关重要。缓存那些经常使用到而用不怎么变化的数据。比如cell中的动态变化的行高,和图片,我们要为他们做好缓存,下次加载这些资源的时候我们就不要再重复请求,而浪费资源又消耗性能。

    对开销大的对象进行约束。

    比如我们经常使用的NSdateFormatter对象,初始化非常慢,Time Profile检测显示估算创建NSdateFormatter对象平均耗33ms左右,设置NSdateFormatter对象的属性也会花费大量时间。所以我们针对这样的对象要加以限制,
    处理方式:
    (1)用static关键字修饰NSdateFormatter对象。
    (2)用GCD中的dispatch_once修饰NSdateFormatter对象。
    (3)用懒加载的方式加载NSdateFormatter对象。这三种方式都是为了防止NSdateFormatter对象重复初始化,减小系统开销。

    正确的选择加载数据的格式。

    Josn格式的数据要比XML要快。不过josn更是适合小文档数据,因为josn数据和XML的dom格式数据都是一次性将整个数据文档加载到内存中,所以用于加载小数据更合适。加载大数据我们做好采用XML的SAX格式,因为SAX是一点点的加载到内存,然后一点点的解析,是流式的,所以更适合大数据的加载。

    数据存储格式的选择。

    • Plist格式和对象序列化都需要读写操作,不适合存储大数据,更适合小数据的存储,因为大数据的写和读都很消耗性能。
    • 大数据的本地持久化选择Sqlite和Core Data性能更好,虽然两者的性能相似,但是苹果官方更推荐使用Core Data。Core Data运用了ORM思想(对象关系映射),对象的属性与表中的字段自动映射,不需要任何SQL语句,也不需要对表进行操作,是一种纯面对对象的数据库存储操作,类似安卓开发中用到Hibenate。

    数据的展示。

    一个页面的数据展示最好要限制每一刷新加载数据的条数,不要过多,限制在10-20之内,新数据的展示和老数据的展示,最好是两个不同URL。还有针对页面中UI中有很多的View,在加载的策略上,完全可以采用多线程技术进行同步加载,只把上半部分放在主线程加载,下半部分放到子线中去加载,这样可以大大降低更新数据的时间,当上半部的数据初始化完毕,下半部分就已经在另一个线程中处理完毕,所以这种加载策略更能优化软件性能。

    运用算法逻辑

    逻辑运算方面的处理要考虑采用做合适的算法处理运算。尽量减少不要运算资源浪费。

    在程序中尽量减少使用webview

    因为我们程序中webView并不像Safari浏览器加载的那么快,没有相应的硬件支持等。

    Autoreleasepool的正确使用

    • 写基于命令行的的程序时,就是没有UI框架,如AppKit等Cocoa框架时。
    • 如果你编写的循环中创建了大量的临时对象;
    • 创建了新的线程。(非Cocoa程序创建线程时才需要)。
    • 长时间在后台运行的任务。

    程序瘦身(未更新中)

    征求APP优化策略

    关于APP性能优化的方法,将在项目实战中持续更新。希望小伙伴们集思广益,都能参与进来,提供更好更完美的优化策略···

    相关文章

      网友评论

        本文标题:APP性能优化汇总

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