> For the complete documentation index, see [llms.txt](https://yongpenglovemimi123.gitbook.io/henry/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yongpenglovemimi123.gitbook.io/henry/ios/ping-guo-ying-yong-bao-chi-hua-mian-liu-chang.md).

# 苹果应用 保持画面流畅

![](https://964606286-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M114Zqgo1V0DJ4FaGQa%2F-M7aEU-86w7vxEF_tw9c%2F-M7aFb0qOBo8tLFIiypt%2Fimage.png?alt=media\&token=c572bba6-b652-4f56-bb18-b685204bbd29)

从上面的图中可以看到，CPU 和 GPU 不论哪个阻碍了显示流程，都会造成掉帧现象。所以开发时，也需要分别对 CPU 和 GPU 压力进行评估和优化。

一，CPU的消耗：（也是避免阻塞主线程，比如你写 while(true){} 100% cpu占用，主线程阻死）

1. 对象的创建： 比如 基于CALayer这一类视图控件，注意的是UI控件系统是不允许在背后线程创建的，只能在主线程创建，但是你可以保持尽量少的创建对象来减少对CPU消耗，通过storyboard创建视图会比通过代码创建消耗的资源多，但是各有各的好处。如果一些比较消耗性能的视图尽量避免。
2. 对象的调整： 减少不必要的层级关系调整，布局更改。&#x20;
3. 布局计算：尽量在一次布局中设置相应的改变，而不是多次频繁的改动布局。
4. Autolayout：在视图超级多的时候会耗时会明显增多，至少200视图起，200视图以内并不明显。&#x20;
5. 文本计算：尽量避免 文本的宽高复杂计算
6. 文本渲染：屏幕上能看到的所有文本内容控件，包括 UIWebView，在底层都是通过 CoreText 排版、绘制为 Bitmap 显示的。常见的文本控件 （UILabel、UITextView 等），其排版和绘制都是在主线程进行的，当显示大量文本时，CPU 的压力会非常大。对此解决方案只有一个，那就是自定义文本控件，用 TextKit 或最底层的 CoreText 对文本异步绘制。尽管这实现起来非常麻烦，但其带来的优势也非常大，CoreText 对象创建好后，能直接获取文本的宽高等信息，避免了多次计算（调整 UILabel 大小时算一遍、UILabel 绘制时内部再算一遍）；CoreText 对象占用内存较少，可以缓存下来以备稍后多次渲染。
7. 图片解码：后台解码bitmap直接生成图片，然后主线程使用。
8. 图像绘制：drawRect方法，由于CoreGraphic是线程安全的，可以在背后线程操作，然后在主线程里面将image赋值给layer.content

二，GPU的消耗：

1. 纹理渲染：所有从内存提交显存的内容，这里涉及到提交到显存的过程和渲染纹理的过程都是在消耗GPU，避免在短时间大量显示图片等内容，如果可以多个图片合成，就显示合成图片。
2. 视图的混合：当视图层级比较复杂，GPU会混合这些视图层级，越复杂的层级，GPU混合就越消耗GPU资源，尽量减少图片和视图层级，也可以提前合成一张图片。
3. 图形的生成：CALayer 的 border，圆角，mask，阴影这些通常会触发离屏渲染，而离屏渲染通常发生在GPU中，当一个tableview出现大量的这种视图，由于GPU需要更长的时间去渲染。导致每秒给到显示卡的图像变少了，也就是FPS变低了，如果FPS太低就会肉眼感觉到明显的卡顿了。 可以使用 CALayer.shouldRasterize 光栅化来转嫁到CPU上来处理，或者用一张带自带圆角的图片进行合成。
