iOS 性能优化

2021-03-12  本文已影响0人  迷失的信徒

iOS的性能优化主要可提现在以前的几个方面:卡顿优化、耗电优化、启动优化、安装包的瘦身。

1、卡顿优化

在了解卡顿优化相关之前我们需要了解屏幕成像原理和卡顿的成因。

屏幕成像原理

我们所看到的动态的屏幕的成像其实和视频一样,都是一帧一帧造成的。为了把显示器的显示过程和系统的视频控制器进行同步,显示器(或者其他硬件)会用硬件时钟产生一系列的定时信号。当电子枪换到新的一行,准备进行扫描时,显示器会发出一个水平同步信号(Horizonal Synchronization),简称HSync;当一帧画面绘制完成后,电子枪回复到原位,准备画下一帧前,显示器会发出一个垂直同步信号(Vertical Synchronization),简称VSync。显示器通常以一个固定的频率进行刷新,这个刷新的频率就是VSync信号产生的频率。

卡顿成因

完成显示的过程:CPU计算数据->GPU进行渲染->屏幕发出VSync信号->成像,假如屏幕已经发出了VSync,但是GPU还没有渲染完成,则只能将上一次的数据显示出来,以至于当前计算的帧数据丢失,这样就产生了卡顿,当前的帧数据计算好后只能等下一周期去渲染了。

CPU(Central Processing Unit,中央处理器)

对象的创建、摧毁、属性的调整、布局的计算、文本的计算和排版、图片的格式转换和解码、图像的绘制(Core Graphics)都是通过CPU来做的。

GPU(Graphics Processing Unit,图形处理器)
图片.png
所要显示的信息一般是通过CPU计算或者解码,经过CPU的数据交给GPU渲染,渲染的工作在帧缓存的地方完成,然后从帧缓存读取数据到视屏控制器上,最终显示在屏幕上。
在iOS中有双缓存机制,前帧缓存、后帧缓存,这样的渲染效率更高。

卡顿解决办法

主要思路就是:尽可能的减少CPU和GPU资源的消耗。
按照60fps的刷帧率,每隔16ms就会产生一个VSync信号,那么针对CPU和GPU有以下优化方案:

CPU
GPU

离屏渲染

在OpenGL中,GPU有两种渲染方式:
On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染操作。
Off-Screen Rendering:在当前屏幕缓冲区外开辟新的缓冲区进行渲染操作。
离屏渲染操作消耗性能的原因:
在整个离屏渲染的操作过程当中,需要多次切换上下文环境,先是从当前屏幕切换到离屏,渲染结束后,将离屏缓冲区的渲染结果显示到屏幕上,上下文环境从离屏切换到当前屏幕,这个过程会造成性能的消耗。
一下操作会触发离屏渲染

但光栅化又会导致离屏渲染,影响图像性能,那么光栅化是否有助于优化性能,就取决于光栅化创建的位图缓存是否被有效复用,而减少渲染的频度,可以视同Instruments进行检测:
当你使用光栅化时,你可以开启“Color Hits Green and Misses Red”,来检查该场景下光栅化是否是一个好的选择。
如果光栅化的图层是绿色,就表示这些缓存被复用;如果是红色就表示缓存会被重复创建,这就表示该处存在性能问题了。
注意:
对于经常变动的内容,这个时候不要开启,否则会造成性能的浪费。

卡顿检测

这里的检测主要是针对主线程执行的耗时操作,可以通过RunLoop来检测:添加Observer到主线程的RunLoop中,通过监听RunLoop状态的切换的耗时,达到监控卡顿的目的。

2、耗电优化

耗电的主要方面:

优化思路

启动优化

App的启动分为两种:冷启动、热启动

App冷启动

冷启动可以分为三个阶段:dyld阶段、Runtime阶段、main阶段。
第一阶段就是处理程序的镜像阶段,第二个阶段是加载本程序的类、分类信息等等的Runtime阶段,最后是调用main函数阶段。

dyld

dyld(Dynamic Link Editor),Apple的动态链接器,可以用来装载Mach-O文件(可执行文件和动态库等)。

图片.png
启动App时,dyld会装载App的可执行文件,同时会递归加载所有依赖的动态库,当dyld把可执行文件、动态库都装载完毕后,会通知Runtime进行做下一步的处理。
Runtime

启动App时,调用map_images 进行可执行文件的内容解析和处理,再load_images中调用call_load_methods调用所有Class和Category的load方法,然后进行objc结构初始化(注册类、初始化类对象等)。然后调用C++静态初始化器和__attribute_((constructor))修饰的函数,到此为止,可执行文件的和动态库中所有的符号(类、协议、方法等)都已经按照格式加载到内存中,被Runtime管理。

main

在Runtime阶段完成后,dyld会调用main函数,接下来是UIApplication函数,AppDelegate的application: didFinishLaunchingWithOptions:函数。

启动优化思路

dyld

虚函数和java中抽象的函数有点类似,但区别是,基类定义的虚函数,子类可以实现也可以不实现,而抽象函数子类一定要实现。

Runtime
main

3、安装包瘦身

安装包(ipa)主要由可执行文件和资源文件组成,若不能妥善的管理则会造成安装包体积越来越大,所以针对资源优化我们可以将资源采取无损压缩,去除没用的资源。

LinkMap

Build Setting -> LD_MAP_FILE_PATH: 设置文件路径 ,Build Setting -> LD_GENERSTE_MAP_FILE -> YES

图片.png
运行程序可看到:
图片.png
打开可看见各种信息:
图片.png
我们可根据这个信息针对某个类进行优化。
上一篇下一篇

猜你喜欢

热点阅读