IOS性能优化方法总结

1.如何提升 tableview 的流畅度?

本质上是降低 CPU、GPU 的工作,从这两个大的方面去提升性能。

  • CPU:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制

  • GPU:纹理的渲染

卡顿优化在 CPU 层面
  • 尽量用轻量级的对象,比如用不到事件处理的地方,可以考虑使用 CALayer 取代 UIView

  • 不要频繁地调用 UIView 的相关属性,比如 frame、bounds、transform 等属性,尽量减少不必要的修改

  • 尽量提前计算好布局,在有需要时一次性调整对应的属性,不要多次修改属性

  • Autolayout 会比直接设置 frame 消耗更多的 CPU 资源

  • 图片的 size 最好刚好跟 UIImageView 的 size 保持一致

  • 控制一下线程的最大并发数量

  • 尽量把耗时的操作放到子线程

    • 文本处理(尺寸计算、绘制)

    • 图片处理(解码、绘制)

卡顿优化在 GPU层面
  • 尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示

  • GPU能处理的最大纹理尺寸是 4096x4096,一旦超过这个尺寸,就会占用 CPU 资源进行处理,所以纹理尽量不要超过这个尺寸

  • 尽量减少视图数量和层次

  • 减少透明的视图(alpha<1),不透明的就设置 opaque 为 YES

  • 尽量避免出现离屏渲染

iOS 保持界面流畅的技巧

1.预排版,提前计算

在接收到服务端返回的数据后,尽量将 CoreText 排版的结果、单个控件的高度、cell 整体的高度提前计算好,将其存储在模型的属性中。需要使用时,直接从模型中往外取,避免了计算的过程。

尽量少用 UILabel,可以使用 CALayer 。避免使用 AutoLayout 的自动布局技术,采取纯代码的方式

2.预渲染,提前绘制

例如圆形的图标可以提前在,在接收到网络返回数据时,在后台线程进行处理,直接存储在模型数据里,回到主线程后直接调用就可以了

避免使用 CALayer 的 Border、corner、shadow、mask 等技术,这些都会触发离屏渲染。

3.异步绘制
4.全局并发线程
5.高效的图片异步加载

5.如何有效降低 APP 包的大小?

降低包大小需要从两方面着手

可执行文件
  • 编译器优化

    • Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default 设置为 YES

    • 去掉异常支持,Enable C++ Exceptions、Enable Objective-C Exceptions 设置为 NO, Other C Flags 添加 -fno-exceptions

  • 利用 AppCode 检测未使用的代码:菜单栏 -> Code -> Inspect Code

  • 编写LLVM插件检测出重复代码、未被调用的代码

资源

资源包括 图片、音频、视频 等

6.日常如何检查内存泄露?

目前我知道的方式有以下几种

  • Memory Leaks

  • Alloctions

  • Analyse

  • Debug Memory Graph

  • MLeaksFinder

泄露的内存主要有以下两种:
  • Laek Memory 这种是忘记 Release 操作所泄露的内存。

  • Abandon Memory 这种是循环引用,无法释放掉的内存。

上面所说的五种方式,其实前四种都比较麻烦,需要不断地调试运行,第五种是腾讯阅读团队出品,效果好一些,感兴趣的可以看一下这两篇文章:

9.什么是 离屏渲染?什么情况下会触发?该如何应对?

离屏渲染就是在当前屏幕缓冲区以外,新开辟一个缓冲区进行操作。

离屏渲染出发的场景有以下:
  • 圆角 (maskToBounds并用才会触发)

  • 图层蒙版

  • 阴影

  • 光栅化

为什么要避免离屏渲染?

CPU GPU 在绘制渲染视图时做了大量的工作。离屏渲染发生在 GPU 层面上,会创建新的渲染缓冲区,会触发 OpenGL 的多通道渲染管线,图形上下文的切换会造成额外的开销,增加 GPU 工作量。如果 CPU GPU 累计耗时 16.67 毫秒还没有完成,就会造成卡顿掉帧。

圆角属性蒙层遮罩 都会触发离屏渲染。指定了以上属性,标记了它在新的图形上下文中,在未愈合之前,不可以用于显示的时候就出发了离屏渲染。

  • 在OpenGL中,GPU有2种渲染方式

    • On-Screen Rendering:当前屏幕渲染,在当前用于显示的屏幕缓冲区进行渲染操作

    • Off-Screen Rendering:离屏渲染,在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作

  • 离屏渲染消耗性能的原因

    • 需要创建新的缓冲区

    • 离屏渲染的整个过程,需要多次切换上下文环境,先是从当前屏幕(On-Screen)切换到离屏(Off-Screen);等到离屏渲染结束以后,将离屏缓冲区的渲染结果显示到屏幕上,又需要将上下文环境从离屏切换到当前屏幕

  • 哪些操作会触发离屏渲染?

    • 光栅化,layer.shouldRasterize = YES

    • 遮罩,layer.mask

    • 圆角,同时设置 layer.masksToBounds = YES、layer.cornerRadius大于0

    • 考虑通过 CoreGraphics 绘制裁剪圆角,或者叫美工提供圆角图片

    • 阴影,layer.shadowXXX,如果设置了 layer.shadowPath 就不会产生离屏渲染

6.如何高性能的画一个圆角?

视图和圆角的大小对帧率并没有什么卵影响,数量才是伤害的核心输出

label.layer.cornerRadius = 5
label.layer.masksToBounds = true

首先上面的方式是不可取的,会触发离屏渲染。

  • 如果能够只用 cornerRadius 解决问题,就不用优化。

  • 如果必须设置 masksToBounds,可以参考圆角视图的数量,如果数量较少(一页只有几个)也可以考虑不用优化。

  • UIImageView 的圆角通过直接截取图片实现,其它视图的圆角可以通过 Core Graphics 画出圆角矩形实现。

12.如何优化 APP 的电量?

程序的耗电主要在以下四个方面:
  • CPU 处理

  • 定位

  • 网络

  • 图像

优化的途径主要体现在以下几个方面:
  • 尽可能降低 CPU、GPU 的功耗。

  • 尽量少用 定时器。

  • 优化 I/O 操作。

    • 不要频繁写入小数据,而是积攒到一定数量再写入

    • 读写大量的数据可以使用 Dispatch_io ,GCD 内部已经做了优化。

    • 数据量比较大时,建议使用数据库

  • 网络方面的优化

    • 减少压缩网络数据 (XML -> JSON -> ProtoBuf),如果可能建议使用 ProtoBuf。

    • 如果请求的返回数据相同,可以使用 NSCache 进行缓存

    • 使用断点续传,避免因网络失败后要重新下载。

    • 网络不可用的时候,不尝试进行网络请求

    • 长时间的网络请求,要提供可以取消的操作

    • 采取批量传输。下载视频流的时候,尽量一大块一大块的进行下载,广告可以一次下载多个

  • 定位层面的优化

    • 如果只是需要快速确定用户位置,最好用 CLLocationManager 的 requestLocation 方法。定位完成后,会自动让定位硬件断电

    • 如果不是导航应用,尽量不要实时更新位置,定位完毕就关掉定位服务

    • 尽量降低定位精度,比如尽量不要使用精度最高的 kCLLocationAccuracyBest

    • 需要后台定位时,尽量设置 pausesLocationUpdatesAutomatically 为 YES,如果用户不太可能移动的时候系统会自动暂停位置更新

    • 尽量不要使用 startMonitoringSignificantLocationChanges,优先考虑 startMonitoringForRegion:

  • 硬件检测优化

    • 用户移动、摇晃、倾斜设备时,会产生动作(motion)事件,这些事件由加速度计、陀螺仪、磁力计等硬件检测。在不需要检测的场合,应该及时关闭这些硬件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值