iOS开发系列之性能优化(上)
本篇主要记录一下我对界面优化上的一些探索。关于时间优化的探索将会在中篇里进行介绍。下篇将主要介绍一些耗电优化、安装包瘦身的探索。
### 1、卡顿原理
要了解卡顿原理,需要对帧缓冲区、垂直同步、CPU 和 GPU 几个词进行一下了解,然后综合起来,就可以得到卡顿的答案。本篇我就按照自己的理解来进行描述,如有不当,欢迎指正。
#### 1.1、帧缓冲区
听起来很高大上,其实就是用来存放每一帧画面数据的一个“仓库”,一个仓库只存放一帧画面的数据,iOS 一直是双缓存,就是有两个仓库,存当前帧数据的叫“正式仓库”,存下一帧数据的叫“预备仓库”。
当正式仓库的数据被取走后,两者身份交换,原来的预备仓库转正为正式仓库,原来的正式仓库变成预备仓库。
#### 1.2、垂直同步 (VSync)
就是一个“信号”,通知 app 该开始准备往预备仓库里存放数据了,系统过一会就要来取,这个时间大概是16毫秒。
#### 1.3、CPU (中央处理器)
主要的工作有:正式对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制。我们可以理解为负责包裹内部的处理工作,简称“打包”。
#### 1.4、GPU (图形处理器)
主要的工作有:将 CPU 计算好的内容进行变换、合成、渲染等处理,然后将渲染结果提交到帧缓冲区。我们可以理解为,对 CPU 给过来的包裹进行分类、排列等操作后,存放到仓库里去,简称“入库”。
#### 1.5、卡顿原理
当收到系统发过来的 VSync “信号”后,CPU 就开始对这一帧画面的数据进行“打包”,然后交给 GPU 进行“入库”操作,存入到“预备仓库”中。
16毫秒后,预备仓库转正,系统开始读取仓库里的数据,如果这个时候,仓库中的数据还没有准备好,那么系统就会大发雷霆,放弃读取仓库中的数据。
那么这个时候,因为系统的宁缺毋滥,导致了显示器上显示的还是上一帧画面,就造成了卡顿的效果。
### 2、性能优化
作为软件开发工程师的我们,既不能延长16毫秒的处理时间,也不能改变系统的脾气,那我们能做的就是尽量在这个时间内完成数据的准备。要么“打包”快一点,要么“入库”快一点,也就是针对 CPU 和 GPU 的工作进行优化,这就是性能优化的工作了。
#### 2.1、CPU 工作之正式对象的创建和销毁
- UITableViewCell 和 UICollectionViewCell 的复用,可以减少 cell 的创建操作;
- 尽量使用轻量级的对象,可以减少对象的创建时间,比如在不需要事件处理的场景里,使用CALayer 比 UIView 会更加合适;
- 表情键盘使用 UICollectionViewCell 代替 UIButton,可以减少对象的创建操作;
- 对象不涉及UI操作,放到后台线程创建;
- 性能敏感的界面,storyborad的资源消耗>代码创建;
- 推迟对象创建的时间,对象放到多个任务中,比如懒加载;
#### 2.2、CPU 工作之对象属性的调整
- UIView 有一个 CALyer 的属性,UIView 负责事件的处理,CALyer 负责图层的绘制和显示。需要注意的是,CALyer本身是没有属性的,所以当改变 UIView 的显示相关的属性如 frame、bounds 和 transform 的时候,会消耗较多的资源,所以减少对这些属性的一些不必要修改,能减小 CPU 的压力;
#### 2.3、CPU 工作之布局计算
- UITableViewCell 高度提前计算并存储,要用的时候直接读取;
- frame 计算好,较少不必要的修改;
- Autolayout会比直接设置frame消耗更多的CPU资源;
#### 2.4、CPU 工作之文本的计算和排版
- 普通文本可以在子线程用 [NSAttributedString boundingRectWithSize:options:context:] 来计算文本宽高,用 -[NSAttributedString drawWithRect:options:context:] 来绘制文本;
- CoreText 对象占用内存较少,当显示大量文本时,可以用 CoreText 对文本异步绘制;
#### 2.5、CPU 工作之图片的格式转换和解码
- 在后台线程先把图片绘制到 CGBitmapContext 中,然后从 Bitmap 直接创建图片;
#### 2.6、CPU 工作之图像的绘制
- UITableViewCell 滑动减速的时候才加载图片,可以参考这个[demo](https://github.com/johnil/VVeboTableViewDemo);
- 加载图片时,imageNamed 方法默认加载图片成功后会内存中缓存图片,下次读取会很快;imageWithContentsOfFile 方法不会缓存图片,大图片可以使用该方法;
#### 2.7、GPU 工作之渲染
- 尽量不要让图片和视图的大小超过 GPU 纹理尺寸上限:4096×4096,不然图片还需要经过 CPU 的处理;
- 尽量减少视图数量和层次,并设置视图为不透明,UIView 的不透明属性 (opaque) 默认为 YES,一般设置背景颜色即可;CALayer 的不透明属性 (opaque) 默认为 NO,需要设置为 YES;
- CALayer 的 border、圆角、阴影、遮罩,通常会触发离屏渲染,尽量少用,圆角属性可以使用 CoreGraphics 绘制或使用圆角图片代替,关于离屏渲染的知识,具体可以参考这篇文章:[iOS 图形性能优化](http://www.cocoachina.com/cms/wap.php?action=article&id=25543);
- 图片的 size 最好刚好跟 UIImageView 的 size 保持一致,这涉及到像素对齐的知识,也可以在上面这篇文章中详细了解;
最后郑重声明,本篇里只是记录一下我的个人理解和代码实践,资料大量参考了这篇文章:[iOS 保持界面流畅的技巧](https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/),作者是写出了 YYKit 框架的大佬,想要深入学习的朋友请移步。
本篇的界面优化就记录到这里,后面会持续更新,欢迎指正。
iOS开发系列之性能优化(上)的更多相关文章
- Android开发系列之性能优化
一直想整理一篇关于Android性能优化的博客,正好今天借鉴一些书籍资料,总结一下自己对于这块的一些认识.相信大家都听说过16ms的原则,即每两个画面之间的绘制时间间隔不能超过16ms,否则人眼能够感 ...
- iOS开发那些事--性能优化–内存泄露问题的解决(转)
内存泄漏问题的解决 内存泄漏(Memory Leaks)是当一个对象或变量在使用完成后没有释放掉,这个对象一直占有着这块内存,直到应用停止.如果这种对象过多内存就会耗尽,其它的应用就无法运行.这个问题 ...
- iOS开发系列--Swift进阶
概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...
- iOS开发系列--通知与消息机制
概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...
- iOS开发系列--让你的应用“动”起来
--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...
- iOS开发系列--让你的应用“动”起来
--iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建 ...
- IOS开发系列 --- 核心动画
原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
- iOS开发系列--让你的应用“动”起来【转载】
概览 原文链接:http://www.cnblogs.com/kenshincui/p/3972100.html 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
- iOS开发系列--通知与消息机制--转
来自:http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户 ...
随机推荐
- 简明Python3教程 首页
A Byte of Python 'A Byte of Python' is a free book on programming using the Python language. It serv ...
- bigdata_zookeeper 可视化界面zkui
安装zkui zookeeper节点的可视化界面有很多种,我使用的是zkui,比较直观,而且可以导入文件,他的Git地址: https://github.com ...
- postgresql && .net core 使用空间数据
这里主要讲遇到的一些报错 增删改查 && 计算部分基本和sql server的空间数据操作一毛一样,感谢微软大大的倾情支持,直接看demo即可(- ̄▽ ̄)- 前往sql server ...
- ASP .NET 返回Json操作结果
返回string var A="..."; var B="..."; $.ajax({ type: "POST", url: "/ ...
- VS发布到IIS Express外网Debug(如微信开发)
主要效果是本机调试网站,将网站发布到某域名(如m16758r728.iok.la),可以进入VS断点,不必再用远程调试!!! 环境 VS2015windows 10操作系统花生壳(可以用其他内网穿透的 ...
- 图像滤镜艺术--PS平均(滤镜-模糊-平均)效果
原文:图像滤镜艺术--PS平均(滤镜-模糊-平均)效果 本文介绍PS中滤镜-模糊-平均模糊的效果实现: 这个效果很简单,原理如下: 1,统计全图像素的R,G,B值得和sumR,sumG,sumB; 2 ...
- Android adb你真的会用吗?
前言 本文基于Android官方文档, 以及个人工作的使用经验, 总结下adb的常用用法, 备忘. 1.adb 简介 adb全名Andorid Debug Bridge. 顾名思义, 这是一个Debu ...
- 数据库的事务日志已满,起因为"LOG_BACKUP"。
问题描述: 数据库的事务日志已满,起因为"LOG_BACKUP". 问题截图: 解决方法: 1).选择数据库–属性—选项—恢复模式–选择简单.2).收缩数据库后,再调回完整. US ...
- 【Windows10 IoT开发系列】Powershell命令行实用程序
原文:[Windows10 IoT开发系列]Powershell命令行实用程序 更新帐户密码: 强烈建议你更新默认的管理员帐户密码.若要更新帐户密码,你可以发出以下命令: net user Admin ...
- Win10的UWP之标题栏的返回键(二)
原文:Win10的UWP之标题栏的返回键(二) 关于Win10的UWP的返回键的第二种处理的方法,是介于标题栏的强行修改,不是像上期的那样直接调用系统内置的API. - - - - - - - - - ...