一、首页启动速度
- 启动过程中,做的事情越少越好。(尽可能将多个接口合并)
- 不在UI上做耗时操作。(数据的处理在子线程中进行,处理完成后通知主线程更新界面)
- 在合适的时机开始后台任务。(例如:用户引导界面就开始加载主页的数据)
- 尽量减少包的大小。
- 优化方法:量化启动时间、启动速度模块化、辅助工具(友盟、听云、Flurry)
二、页面浏览速度
- JSON 的处理。(iOS 自带的NSJSONSerialization,Jsonkit,SBJson)
- 数据的分页处理。(后端数据多的话应该用分页处理)
- 数据压缩。(大数据也可以压缩返回,减少流量,加快反应速度)
- 内容缓存。(例如网易新闻最新列表都是要缓存到本地,从本地加载,可以缓存到数据,内存,根据情况而定)
- 延迟加载tableView。(例如:app 有5个tableView,可以先加载第一个显示的tableView,按需要加载)
- 算法优化。(核心算法的优化,例如有些app 的联系人通过首字母排序)
三、操作流程
- tableView 的优化。(cell 的性能)
- ViewController加载优化。(不同view直接的跳转,可以提前准备好数据)
四、数据库优化
- 数据库设计面上的重构。
- 查询语句的优化。
- 分库分表。(数据太多的时候可以分不同的表或库)
五、服务端和客户端的交互优化
- 客户端尽量减少请求。
- 服务器端尽量做多的逻辑处理。
- 服务器端和客户端采取推拉结合的方式。(可以利用一些同步机制)
- 通信协议的优化。(减少报文的大小)
- 电量的优化。(尽量不要用后台运行)
六、非技术性能优化
- 产品设计的逻辑性。(产品设计一定要符合逻辑,或者逻辑尽量简单,有时候可能会废了好大劲才完成一个小逻辑)
- 界面交互规范。(每个模块界面尽量统一,符合操作习惯)
- 代码规范。(可以隐形带来app 性能提高,比如用 if else 还是switch,或者用! 还是==)
- code review。(坚持code review,持续代码重构,减少代码的复杂度)
- 日常交流。(经常分享一些代码,或者逻辑中遇到的一些坑)
启动时间
a. 链接和接入:可以在time profile 中显示dyld载入库函数,库会映射到地址空间,同事完成绑定及静态初始化。
b. UIKit 初始化:如果rootViewController 由XIB 实现的,也会在启动的时候被初始化。
c. 应用回调:调用UIApplicationDeleagte的回调:application:didFinishLaunchingWithOptions
d. 第一次Core Animation调用:在启动后的方法-[UIApplication _resportAppLaunchFinished]中调用CA::Transaction::commit实现第一帧画面的绘制。如果你的程序启动很慢,能 做的首先是将与显示第一屏画面无关的操作放到之后执行;如果是用XIB文件load第一屏,XIB文件中的View层也要如果扁平,不要有太多图层。用户响应
如何让用户能感觉到app响应迅速呢?当然是app 用户所触发的操作能够立刻响应,即用户事件(User Event)能够被主线程的run loop及时处理。什么是run loop?可以想象成一个处理事件的select多路复用。主线程中的run loop 当然主要是为了处理用户产生的事件,例如:点击、滚动等。
要让主线程run loop 更好的响应用户事件,工程师尽量减少主线程干重活的时间,尤其是读文件,网络操作,大量运算这类重活,如果是阻塞操作那就是大忌了。我们可以用多线程(GCD、NSThread、NSOperationQueue)将这类重活移除在主线程,这属于显式并发。还有隐式并发,例如UIView 和CALayer的动画,layer 的绘制和png 图片的解码都是在另一个子线程中进行的。除了使用多线程技术减轻主线程的负担外,减少主线程阻塞也是提升用户体验的一个方法。使用instruments 中 time profile 工具中的“recod thread waiting”选项可以统计出app 运行时各个线程的阻塞情况,例如:文件读写 read/write 、网络读写send/recv 、加锁psynch_mutex_wait 等。instruments 中的system trace工具能够记录所有底层系统调用。内存
内存问题从来都是iOS app 老大难的问题,搞不好程序就爆了 。由于iOS系统没有Swap文件,在内存不足时会将只读数据(例如code page)从内存中移出,需要的时候再从disk上读如内存;可读写数据不会被系统从内存中移出,然而如果占用的内存达到一个阈值,系统会发出相应的通知和回调让应用release对象以回收内存,如果仍然不能减少内存使用量,系统会直接关闭应用。尤其是iOS 5.0之后,如果你的app收到了memory warning,那么脑袋也是和其他app一样放在了案板上,随时有可能被kill掉,并不是说一定会先Kill掉在后台的app。
App使用的内存除了我们在堆上分配的内存外(+[NSobject alloc]/malloc),还会有更多使用内存的地方,比如代码和全局数据(TEXT和DATA),线程栈,图片,view 的layer backing store等等。因此处理内存问题,绝不仅仅是我们开发app时尽量少申请内存那么简单。可以用instruments 来调试内存问题。allocation 和 leaks。图形和动画
a. Color Blended Layers
Instruments可以在物理机上显示出被混合的图层Blended Layer(用红色标注),Blended Layer是因为这些Layer是透明的(Transparent),系统在渲染这些view时需要将该view和下层view混合(Blend)后才能计算出该像素点的实际颜色,如果这种blended layer很多,那么在滚动列表时就甭想有流畅的效果。
解决blended layer问题也很简单,检查红色区域view的opaque属性,记得设置成YES;检查backgroundColor属性是不是[UIColor clearColor],要知道背景颜色为clear color那可是图形性能的大敌,基本意味着blended layer是跑不了的了,为什么?自己思考一下:)
b. Color Hits Green and Misses Red
很多视图Layer由于Shadow、Mask和Gradient等原因渲染很高,因此UIKit提供了API用于缓存这些Layer:[layer setShouldRasterize:YES],系统会将这些Layer缓存成Bitmap位图供渲染使用,如果失效时便丢弃这些Bitmap重新生成。图层Rasterization栅格化好处是对刷新率影响较小,坏处是删格化处理后的Bitmap缓存需要占用内存,而且当图层需要缩放时,要对删格化后的Bitmap做额外计算。 使用这个选项后时,如果Rasterized的Layer失效,便会标注为红色,如果有效标注为绿色。当测试的应用频繁闪现出红色标注图层时,表明对图层做的Rasterization作用不大。
c. Color Misaligned Images
Misaligned Image表示要绘制的点无法直接映射到频幕上的像素点,此时系统需要对相邻的像素点做anti-aliasing反锯齿计算,增加了图形负担,通常这种问题出在对某些View的Frame重新计算和设置时产生的。
上图中被标注为黄色的图层,这是由于图层显示的是被缩放后的图片,如果这些图片是通过网络下载的,可以通过程序更新为确定的绘制大小来解决。还有些系统Navigation Bar和Tool Bar的背景图片使用的是拉伸(Streched)图片,也会被表示为黄色,这是属于正常情况,通常无需修改。这种问题一般对性能影响不大,而是可能会在边缘处虚化。
d. Color Offscreen-Rendered Yellow
Offscreen-Rendering离屏渲染意思是iOS要显示一个视图时,需要先在后台用CPU计算出视图的Bitmap,再交给GPU做Onscreen-Rendering显示在屏幕上,因为显示一个视图需要两次计算,所以这种Offscreen-Rendering会导致app的图形性能下降。
大部分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。
e. 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绘制的内容。 这三个选项对图形性能的分析意义较小,通常仅作为参考。文件和网络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连接等),用得不多,做网络使用状况分析时用用还行。