本篇主要记录一下我对界面优化上的一些探索。关于时间优化的探索将会在中篇里进行介绍。下篇将主要介绍一些耗电优化、安装包瘦身的探索。php
要了解卡顿原理,须要对帧缓冲区、垂直同步、CPU 和 GPU 几个词进行一下了解,而后综合起来,就能够获得卡顿的答案。本篇我就按照本身的理解来进行描述,若有不当,欢迎指正。ios
听起来很高大上,其实就是用来存放每一帧画面数据的一个“仓库”,一个仓库只存放一帧画面的数据,iOS 一直是双缓存,就是有两个仓库,存当前帧数据的叫“正式仓库”,存下一帧数据的叫“预备仓库”。git
当正式仓库的数据被取走后,二者身份交换,原来的预备仓库转正为正式仓库,原来的正式仓库变成预备仓库。github
就是一个“信号”,通知 app 该开始准备往预备仓库里存放数据了,系统过一会就要来取,这个时间大概是16毫秒。缓存
主要的工做有:正式对象的建立和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制。咱们能够理解为负责包裹内部的处理工做,简称“打包”。性能优化
主要的工做有:将 CPU 计算好的内容进行变换、合成、渲染等处理,而后将渲染结果提交到帧缓冲区。咱们能够理解为,对 CPU 给过来的包裹进行分类、排列等操做后,存放到仓库里去,简称“入库”。app
当收到系统发过来的 VSync “信号”后,CPU 就开始对这一帧画面的数据进行“打包”,而后交给 GPU 进行“入库”操做,存入到“预备仓库”中。框架
16毫秒后,预备仓库转正,系统开始读取仓库里的数据,若是这个时候,仓库中的数据尚未准备好,那么系统就会发脾气,放弃读取仓库中的数据。异步
那么这个时候,由于系统的宁缺毋滥,致使了显示器上显示的仍是上一帧画面,就形成了卡顿的效果。布局
做为软件开发工程师的咱们,既不能延长16毫秒的处理时间,也不能改变系统的脾气,那咱们能作的就是尽可能在这个时间内完成数据的准备。要么“打包”快一点,要么“入库”快一点,也就是针对 CPU 和 GPU 的工做进行优化,这就是性能优化的工做了。
UITableViewCell 和 UICollectionViewCell 的复用,能够减小 cell 的建立操做;
尽可能使用轻量级的对象,能够减小对象的建立时间,好比在不须要事件处理的场景里,使用CALayer 比 UIView 会更加合适;
表情键盘使用 UICollectionViewCell 代替 UIButton,能够减小对象的建立操做;
对象不涉及UI操做,放到后台线程建立;
性能要求严格的界面,storyborad的资源消耗>代码建立;
推迟对象建立的时间,对象放到多个任务中,好比懒加载;
UITableViewCell 高度提早计算并存储,要用的时候直接读取;
frame 计算好,较少没必要要的修改;
Autolayout会比直接设置frame消耗更多的CPU资源;
普通文本能够在子线程用 [NSAttributedString boundingRectWithSize:options:context:] 来计算文本宽高,用 -[NSAttributedString drawWithRect:options:context:] 来绘制文本;
CoreText 对象占用内存较少,当显示大量文本时,能够用 CoreText 对文本异步绘制;
UITableViewCell 滑动减速的时候才加载图片,能够参考这个demo;
加载图片时,imageNamed 方法默认加载图片成功后会内存中缓存图片,下次读取会很快;imageWithContentsOfFile 方法不会缓存图片,大图片可使用该方法;
尽可能不要让图片和视图的大小超过 GPU 纹理尺寸上限:4096×4096,否则图片还须要通过 CPU 的处理;
尽可能减小视图数量和层次,并设置视图为不透明,UIView 的不透明属性 (opaque) 默认为 YES,通常设置背景颜色便可;CALayer 的不透明属性 (opaque) 默认为 NO,须要设置为 YES;
CALayer 的 border、圆角、阴影、遮罩,一般会触发离屏渲染,尽可能少用,圆角属性可使用 CoreGraphics 绘制或使用圆角图片代替,关于离屏渲染的知识,具体能够参考这篇文章:iOS 图形性能优化;
图片的 size 最好恰好跟 UIImageView 的 size 保持一致,这涉及到像素对齐的知识,也能够在上面这篇文章中详细了解;
最后郑重声明,本篇里只是记录一下个人我的理解和代码实践,资料大量参考了这篇文章:iOS 保持界面流畅的技巧,做者是写出了 YYKit 框架的大牛,想要深刻学习的朋友请移步。
本篇的界面优化就记录到这里,后面会持续更新,欢迎指正。