前言:首先我们来了解一下CPU
和GPU
CPU
,中央处理器,主要负责对象的创建和销毁,对象的属性调整,控件的布局计算,文本的计算和排版,图片的格式转换和解码,图像的绘制;
GPU
,图形处理器,主要是对纹理的渲染;
- 屏幕显示原理:要在屏幕上显示视图,需要
CPU
和GPU
一起协作,CPU
计算好显示的内容提交到GPU
,GPU
渲染完成后将结果放到帧缓存区,随后视频控制器会按照VSync
信号逐行读取帧缓冲区的数据,经过可能的数模转换传递给显示器显示. - 卡顿原因:
由于垂直同步机制,如果在一个vsync
时间内,CPU
或者GPU
没有完成内容提交,那么这一帧就会被丢弃,等待下一次机会显示,而这时显示屏因为没有新的刷新,会保留之前的内容不变,这就造成了卡顿;
性能优化解决方案:
一、CPU方面
- 尽量使用轻量级的对象,比如用不到事件处理的地方,可以考虑使用
CALayer
代替UIView
;因为CALayer
内部并没有属性,当调用属性方法时,它内部是通过运行时resolveInstanceMethod
为对象临时添加一个方法,并把对应属性值保存到内部的一个Dictionary
里,同时还会通知delegate
、创建动画等等,非常消耗资源; - 不需要频繁调用
UIView
的相关属性,比如frame和bounds的时候,尽量介绍不必要的修改; - 尽量提前计算好布局,在有需要时一次性调整相关属性,不要多次修改属性;
-
AutoLayout
会比直接设置frame
消耗更多的CPU
资源; - 图片的
size
最好刚好和UIImageView
的size
保持一致; - 控制线程的最大并发数量;
- 尽量把耗时的操作放到子线程中去。
附:
UITableView
优化:
- 正确使用
reuseIdentifier
来重用cell
;- 尽量减少使用不透明的视图;
- 避免渐变,图片缩放;
- 缓冲行高;
- cell内容是下载的话,用异步加载,缓冲结果;
- 使用
shadowPath
来画阴影;- 减少
subViews
的数量;- 使用正确的数据结构存储数据。
二、GPU方面
- 尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示;
- 尽量减少视图数量和层次;
- 减少使用透明的视图;
- 尽量避免出现离屏渲染;
注意:在
OpenGL
中,GPU
有两种渲染方式:
1.On - Screen Rendering 当前屏幕渲染,在当前用于显示的屏幕缓冲区进行缓冲操作;
2.Off - Screen Rendering 离屏渲染,在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作;
离屏渲染消耗性能的原因:
1.需要开辟新的缓冲区
2.离屏渲染的整个过程,需要多次切换上下文环境,先是当前屏幕切换到离屏,等到离屏渲染结束后,将离屏缓冲区的结果显示,又要重新切换
哪些操作会触发离屏渲染?
1.栅格化,设置layer.shouldRasterize
2.遮罩,设置layer.maskToBounds
3.圆角,设置layer.cornerRadius
4.阴影,可设置layer.shadowPath
三、耗电方面
首先我们要明白耗电的主要来源:
-
CPU
处理过程; - 网络方面;
- 定位方面;
定位优化:
· 如果只是需要快速确定用户的位置,最好用CLLocationManager
的request
方法,定位后自动让定位硬件断电;
· 如果不是导航应用,尽量不要实时更新位置;
· 尽量降低定位精度;
· 需要后台定位时,尽量设置pauseLocationUpdatesAutomatically
为YES
;
· 尽量不要使用startMonitoringSignificantLocationChanges
。 - 图片方面;
四、APP启动优化
- 冷启动:从零开始启动
APP
; - 热启动:
APP
已经在内存中,在后台存活着,在后台点击图标的时候启动APP
;
冷启动优化:
-
dyld
,减少动态库,合并一些动态库;减少Objc
类,分类的数量,selector
的数量;减少C++
虚函数数量;swift
尽量使用struct
; - 使用
+initialize
和dispatch_once
; - 在不需要影响用户交互体验的情况下,使用懒加载;
冷启动的三个阶段:
-
dyld
动态链接库装载可执行文件,动态库; - 使用
runtime
调用处理类,分类方法,``objc结构初始化; -
main
函数;
网友评论