苹果应用 保持画面流畅
最后更新于
最后更新于
从上面的图中可以看到,CPU 和 GPU 不论哪个阻碍了显示流程,都会造成掉帧现象。所以开发时,也需要分别对 CPU 和 GPU 压力进行评估和优化。
一,CPU的消耗:(也是避免阻塞主线程,比如你写 while(true){} 100% cpu占用,主线程阻死)
对象的创建: 比如 基于CALayer这一类视图控件,注意的是UI控件系统是不允许在背后线程创建的,只能在主线程创建,但是你可以保持尽量少的创建对象来减少对CPU消耗,通过storyboard创建视图会比通过代码创建消耗的资源多,但是各有各的好处。如果一些比较消耗性能的视图尽量避免。
对象的调整: 减少不必要的层级关系调整,布局更改。
布局计算:尽量在一次布局中设置相应的改变,而不是多次频繁的改动布局。
Autolayout:在视图超级多的时候会耗时会明显增多,至少200视图起,200视图以内并不明显。
文本计算:尽量避免 文本的宽高复杂计算
文本渲染:屏幕上能看到的所有文本内容控件,包括 UIWebView,在底层都是通过 CoreText 排版、绘制为 Bitmap 显示的。常见的文本控件 (UILabel、UITextView 等),其排版和绘制都是在主线程进行的,当显示大量文本时,CPU 的压力会非常大。对此解决方案只有一个,那就是自定义文本控件,用 TextKit 或最底层的 CoreText 对文本异步绘制。尽管这实现起来非常麻烦,但其带来的优势也非常大,CoreText 对象创建好后,能直接获取文本的宽高等信息,避免了多次计算(调整 UILabel 大小时算一遍、UILabel 绘制时内部再算一遍);CoreText 对象占用内存较少,可以缓存下来以备稍后多次渲染。
图片解码:后台解码bitmap直接生成图片,然后主线程使用。
图像绘制:drawRect方法,由于CoreGraphic是线程安全的,可以在背后线程操作,然后在主线程里面将image赋值给layer.content
二,GPU的消耗:
纹理渲染:所有从内存提交显存的内容,这里涉及到提交到显存的过程和渲染纹理的过程都是在消耗GPU,避免在短时间大量显示图片等内容,如果可以多个图片合成,就显示合成图片。
视图的混合:当视图层级比较复杂,GPU会混合这些视图层级,越复杂的层级,GPU混合就越消耗GPU资源,尽量减少图片和视图层级,也可以提前合成一张图片。
图形的生成:CALayer 的 border,圆角,mask,阴影这些通常会触发离屏渲染,而离屏渲染通常发生在GPU中,当一个tableview出现大量的这种视图,由于GPU需要更长的时间去渲染。导致每秒给到显示卡的图像变少了,也就是FPS变低了,如果FPS太低就会肉眼感觉到明显的卡顿了。 可以使用 CALayer.shouldRasterize 光栅化来转嫁到CPU上来处理,或者用一张带自带圆角的图片进行合成。