性能监控-②其他

性能优化

[toc]

目录

帧率优化?卡顿优化?

Flutter DevTools 的视频使用教程:轻松调试和提高 APP 性能

一、耗电量、耗流量优化

< 返回目录

通过

1
2
3
4
5
6
①优化位置服务(尽量降低定位精度)、
②网络操作(减少传输、压缩数据、缓存数据)、
③任务处理(减少任务处理量、按需处理,常见于一些后台任务的处理,比如不需要计算里程时候,鹰眼服务可以先关闭)、
④内容更新(减少app使用的视图数量、去除不必要的内容更新)、
⑤定时器(降低触发频率、及时关闭不再需要的重复性定时器)
>

优化参考文章:iOS进阶–App功耗优化看这篇就够了

定位服务:按需取用,定位频率该降低降低,该关闭关闭

根据位置特性对静止不动的点、位置变化小的点、位置变化大的点,结合不同业务决定位置上报情况,减少不必要的上报,降低耗电量与节省流量。

相似问题参考:解决iOS地图持续定位耗电问题

网络请求优化的

这个需要和后台API一起优化,尽量减少不必要的请求,比如一次API请求尽量把客户端要用到的数据都返回过来,而不是要通过多个请求去返回,同时最好注意数据分页,不要几万条数据都扔给客户端了。

CPU:

使用 Instruments 中的 Time Profile 时间分析工具用来检测应用CPU的使用情况。 定位 app 使用过程中占用高CPU、耗时长的地方。

使用方法参考:Instrument 的 Time Profiler总结

Timer:合理使用Timer数和Timer时间间隔,不宜太短,满足需求即可

设置上报检测计时器(一般设为1秒,但合理的是取不同业务上报频率的最大公约数,比如报班状态下需要5秒上传一次位置,未报班状态只需要20上传一次位置,则取5秒)

合理使用线程,线程适量,不宜过多,不要阻塞主线程

太多线程会导致消耗大量内存(在iOS中,如果把需要消耗大量时间的操作放在主线程上面,会妨碍主线程中被称为RunLoop的主循环的执行,从而导致不能更新用户界面、应用程序的画面长时间停滞等问题。)。

优化算法,减少循环次数

还有关键的就是图片尺寸了,最好客户端需要啥尺寸,服务端就直接给啥尺寸,而不是到客户端上再缩放。

二、内存优化、内存泄露处理

< 返回目录

1、正确的地方使用 reuseIdentifier

2、内存泄漏

1、使用Product-Analyze分析内存泄
利用Product-Analyze分析内存泄露,并不能把所有的内存泄露查出来,因为有的内存泄露是在运行时,用户操作时才产生的。那就需要用到Instruments了。

2、使用Instruments检测定位并解决iOS内存泄露

三、其他优化

< 返回目录

问题:优化多线程处理,改善多线程嵌套严重,请求耗时的问题

解决:优化多线程处理,改善多线程嵌套严重,请求耗时的问题。

详细:原本项目,采用多线程嵌套的同步方式处理多个线程请求到数据后,再执行最后操作。经优化多线程处理为异步执行时,改善了多线程嵌套严重,请求耗时的问题。

定时器使用的优化

问题:定时器多,其在主线程

为什么要在非主线程创建NSTimer

将 timer 添加到主线程的Runloop里面本身会增加线程负荷
如果主线程因为某些原因阻塞卡顿了,timer 定时任务触发的时间精度肯定也会受到影响
有些定时任务不是UI相关的,本来就没必要在主线程执行,给主线程增加不必要的负担。当然也可以在定时任务执行时,手动将任务指派到非主线程上,但这也是有额外开销的。

iOS 应用性能调优其他参考:

耗时(instruments的Time Profiler)、卡顿(主线程)

iOS app性能优化的那些事

iOS应用性能调优的25个建议和技巧

四、渲染

参考文章:iOS 渲染原理解析

1、渲染原理CPU 与 GPU

  • CPU(Central Processing Unit):现代计算机整个系统的运算核心、控制核心。
  • GPU(Graphics Processing Unit):可进行绘图运算工作的专用微处理器,是连接计算机和显示终端的纽带。

GPU 的渲染流程图

GPU 的渲染流程图

1、Application 应用处理阶段:得到图元

这个阶段具体指的就是图像在应用中被处理的阶段,此时还处于 CPU 负责的时期。在这个阶段应用可能会对图像进行一系列的操作或者改变,最终将新的图像信息传给下一阶段。这部分信息被叫做图元(primitives),通常是三角形、线段、顶点等。

2、Geometry 几何处理阶段:处理图元

3、Rasterization 光栅化阶段:图元转换为像素

光栅化的主要目的是将几何渲染之后的图元信息,转换为一系列的像素,以便后续显示在屏幕上。这个阶段中会根据图元信息,计算出每个图元所覆盖的像素信息等,从而将像素划分成不同的部分。

img

一种简单的划分就是根据中心点,如果像素的中心点在图元内部,那么这个像素就属于这个图元。如上图所示,深蓝色的线就是图元信息所构建出的三角形;而通过是否覆盖中心点,可以遍历出所有属于该图元的所有像素,即浅蓝色部分。

4、Pixel 像素处理阶段:处理像素,得到位图

经过上述光栅化阶段,我们得到了图元所对应的像素,此时,我们需要给这些像素填充颜色和效果。所以最后这个阶段就是给像素填充正确的内容,最终显示在屏幕上。这些经过处理、蕴含大量信息的像素点集合,被称作位图(bitmap)。

2. 屏幕成像与卡顿

屏幕撕裂 Screen Tearing

CPU+GPU 的渲染流程是一个非常耗时的过程。如果在电子束开始扫描新的一帧时,位图还没有渲染好,而是在扫描到屏幕中间时才渲染完成,那么已扫描的部分和未扫描的部分就不是同一帧图像,这就造成屏幕撕裂。

解决屏幕撕裂、提高显示效率的一个策略就是使用垂直同步信号 Vsync 与双缓冲机制 Double Buffering。

屏幕卡顿的本质

手机使用卡顿的直接原因,就是掉帧。前文也说过,屏幕刷新频率必须要足够高才能流畅。对于 iPhone 手机来说,屏幕最大的刷新频率是 60 FPS,一般只要保证 50 FPS 就已经是较好的体验了。但是如果掉帧过多,导致刷新频率过低,就会造成不流畅的使用体验。

CALayer 与 UIView 的关系

当我们创建一个 UIView 的时候,UIView 会自动创建一个 CALayer,为自身提供存储 bitmap 的地方(也就是前文说的 backing store),并将自身固定设置为 CALayer 的代理。

核心关系

  1. CALayer 是 UIView 的属性之一,负责渲染和动画,提供可视内容的呈现。
  2. UIView 提供了对 CALayer 部分功能的封装,同时也另外负责了交互事件的处理。

有了这两个最关键的根本关系,那么下面这些经常出现在面试答案里的显性的异同就很好解释了。举几个例子:

  • 相同的层级结构:我们对 UIView 的层级结构非常熟悉,由于每个 UIView 都对应 CALayer 负责页面的绘制,所以 CALayer 也具有相应的层级结构。
  • 部分效果的设置:因为 UIView 只对 CALayer 的部分功能进行了封装,而另一部分如圆角、阴影、边框等特效都需要通过调用 layer 属性来设置。
  • 是否响应点击事件:CALayer 不负责点击事件,所以不响应点击事件,而 UIView 会响应。
  • 不同继承关系:CALayer 继承自 NSObject,UIView 由于要负责交互事件,所以继承自 UIResponder。

当然还剩最后一个问题,为什么要将 CALayer 独立出来,直接使用 UIView 统一管理不行吗?为什么不用一个统一的对象来处理所有事情呢?

这样设计的主要原因就是为了职责分离,拆分功能,方便代码的复用。通过 Core Animation 框架来负责可视内容的呈现,这样在 iOS 和 OS X 上都可以使用 Core Animation 进行渲染。与此同时,两个系统还可以根据交互规则的不同来进一步封装统一的控件,比如 iOS 有 UIKit 和 UIView,OS X 则是AppKit 和 NSView。