- 布局计算:如果视图层级过于复杂,当试图呈现或者修改的时候,计算图层帧率就会消耗一部分时间,
- 视图懒加载:
iOS
只会当视图控制器的视图显示到屏幕上才会加载它,这对内存使用和程序启动时间很有好处,但是当呈现到屏幕之前,按下按钮导致的许多工作都不会被及时响应。比如,控制器从数据局中获取数据, 或者视图从一个xib
加载,或者涉及iO图片显示都会比CPU正常操作慢得多。 - 解压图片:PNG或者JPEG压缩之后的图片文件会比同质量的位图小得多。但是在图片绘制到屏幕上之前,必须把它扩展成完整的未解压的尺寸(通常等同于图片宽 x 长 x 4个字节)。为了节省内存,
iOS
通常直到真正绘制的时候才去解码图片。根据你加载图片的方式,第一次对图层内容赋值的时候(直接或者间接使用 UIImageView )或者把它绘制到Core Graphics
中,都需要对它解压,这样的话,对于一个较大的图片,都会占用一定的时间。 - Core Graphics绘制:如果对视图实现了
drawRect:
或drawLayer:inContext:
方法,或者CALayerDelegate
的方法,那么在绘制任何东西之前都会产生一个巨大的性能开销。为了支持对图层内容的任意绘制,Core Animation
必须创建一个内存中等大小的寄宿图片。然后一旦绘制结束之后, 必须把图片数据通过IPC
传到渲染服务器。在此基础上,Core Graphics
绘制就会变得十分缓慢,所以在一个对性能十分挑剔的场景下这样做十分不好。 - 图层打包:当图层被成功打包,发送到渲染服务器之后,
CPU
仍然要做如下工作:为了显示 屏幕上的图层,Core Animation
必须对渲染树种的每个可见图层通过OpenGL
循环转换成纹理三角板。由于GPU
并不知晓Core Animation
图层的任何结构,所以必须要由CPU
做这些事情。这里CPU
涉及的工作和图层个数成正比,所以如果在你的层 级关系中有太多的图层,就会导致CPU
没一帧的渲染,即使这些事情不是你的应用 程序可控的。
有了上述的操作点,对应每个点我们都能对其进行优化,达到整体渲染效率的提升,下面是笔者的优化方案:
1.过于复杂的布局计算:如果这是一个cell的话,我们可以提前提前全部绘制好,然后再根据需要隐藏和显示。如果这部分可以不包含点击事件也可以把复杂的布局绘制成一张图,到时候直接显示就行。
2.视图懒加载带来的诟病:懒加载加载这个界面的时候,还没有请求到数据时,需要加载请求数据的视图上就会显示“NULL”字样,之后请求到了数据在刷新界面赋值就OK了。 当你网络很慢的时候,就会显示NULL字样很久,体验不好。推荐的解决如下:
- 赋值之前先对数据源做判断,如果是nil,直接return掉,不赋值;当确保不为nil时在赋值;
- 先请求数据,请求到了数据之后,在加载视图,这时候会出现一个问题,就是当网络很慢的时候,请求数据很慢,这时候整个界面就是一个空白,处理方法是加上一个加载进度条,这样交互会稍微好点。
- 创建视图的时候,先对其附一个初始值,随便或是写一个空也可以
3.解压图片:子线程提前解码,降低采样率以后再提前解码,现有的快速简单的方法
4.Core Graphics绘制:少写视图实现drawRect:
或drawLayer:inContext:
方法,或者 CALayerDelegate
的方法
5.图层打包:减少图层数量,和第一条类似