iOS开发教程之常见的性能优化技巧

前言

性能问题的主要原因是什么,原因有相同的,也有不同的,但归根到底,不外乎内存使用、代码效率、合适的策略逻辑、代码质量、安装包体积这一类问题。

但从用户体验的角度去思考,当我们置身处地得把自己当做用户去玩一款应用时候,那么都会在意什么呢?假如正在玩一款手游,首先一定不希望玩着玩着突然闪退,然后就是不希望卡顿,其次就是耗电和耗流量不希望太严重,最后就是安装包希望能小一点。简单归类如下:

快:使用时避免出现卡顿,响应速度快,减少用户等待的时间,满足用户期望。
稳:不要在用户使用过程中崩溃和无响应。
省:节省流量和耗电,减少用户使用成本,避免使用时导致手机发烫。
小:安装包小可以降低用户的安装成本。

一、快

应用启动慢,使用时经常卡顿,是非常影响用户体验的,应该尽量避免出现。卡顿的场景有很多,按场景可以分为4类:UI 绘制、应用启动、页面跳转、事件响应。引起卡顿的原因很多,但不管怎么样的原因和场景,最终都是通过设备屏幕上显示来达到用户,归根到底就是显示有问题,

根据iOS 系统显示原理可以看到,影响绘制的根本原因有以下两个方面:

1.绘制任务太重,绘制一帧内容耗时太长。
2.主线程太忙,根据系统传递过来的 VSYNC 信号来时还没准备好数据导致丢帧。

绘制耗时太长,有一些工具可以帮助我们定位问题。主线程太忙则需要注意了,主线程关键职责是处理用户交互,在屏幕上绘制像素,并进行加载显示相关的数据,所以特别需要避免任何主线程的事情,这样应用程序才能保持对用户操作的即时响应。总结起来,主线程主要做以下几个方面工作:

1.UI 生命周期控制
2.系统事件处理
3.消息处理
4.界面布局
5.界面绘制
6.界面刷新

除此之外,应该尽量避免将其他处理放在主线程中,特别复杂的数据计算和网络请求等。

二、稳

应用的稳定性定义很宽泛,影响稳定性的原因很多,比如内存使用不合理、代码异常场景考虑不周全、代码逻辑不合理等,都会对应用的稳定性造成影响。其中最常见的两个场景是:Crash 和 ANR,这两个错误将会使得程序无法使用,比较常用的解决方式如下:

1.提高代码质量。比如开发期间的代码审核,看些代码设计逻辑,业务合理性等。
2.代码静态扫描工具。常见工具有Clang Static Analyzer、OCLint、Infer等等。
3.Crash监控。把一些崩溃的信息,异常信息及时地记录下来,以便后续分析解决。
4.Crash上传机制。在Crash后,尽量先保存日志到本地,然后等下一次网络正常时再上传日志信息。

三、省

在移动设备中,电池的重要性不言而喻,没有电什么都干不成。对于操作系统和设备开发商来说,耗电优化一致没有停止,去追求更长的待机时间,而对于一款应用来说,并不是可以忽略电量使用问题,特别是那些被归为“电池杀手”的应用,最终的结果是被卸载。因此,应用开发者在实现需求的同时,需要尽量减少电量的消耗。

1.CPU

不论用户是否正在直接使用, CPU 都是应用所使用的主要硬件, 在后台操作和处理推送通知时, 应用仍然会消耗 CPU 资源
应用计算的越多,消耗的电量越多.在完成相同的基本操作时, 老一代的设备会消耗更多的电量, 计算量的消耗取决于不同的因素

2.网络

智能的网络访问管理可以让应用响应的更快,并有助于延长电池寿命.在无法访问网络时,应该推迟后续的网络请求, 直到网络连接恢复为止. 此外,应避免在没有连接 WiFi 的情况下进行高宽带消耗的操作.比如视频流, 众所周知,蜂窝无线系统(LTE,4G,3G等)对电量的消耗远远大于 WiFi信号,根源在于 LTE 设备基于多输入,多输出技术,使用多个并发信号以维护两端的 LTE 链接,类似的,所有的蜂窝数据链接都会定期扫描以寻找更强的信号. 因此:我们需要

1)在进行任何网络操作之前,先检查合适的网络连接是否可用
2)持续监视网络的可用性,并在链接状态发生变化时给与适当的反馈
3).定位管理器和** GPS**

我们都知道定位服务是很耗电的,使用 GPS 计算坐标需要确定两点信息:

1)时间锁每个 GPS 卫星每毫秒广播唯一一个1023位随机数, 因而数据传播速率是1.024Mbit/s GPS 的接收芯片必须正确的与卫星的时间锁槽对齐
2)频率锁 GPS 接收器必须计算由接收器与卫星的相对运动导致的多普勒偏移带来的信号误差

计算坐标会不断的使用 CPU 和 GPS 的硬件资源,因此他们会迅速的消耗电池电量, 那么怎么减少呢?

1)关闭无关紧要的特性

判断何时需要跟踪位置的变化, 在需要跟踪的时候调用 startUpdatingLocation方法,无须跟踪时调用stopUpdatingLocation方法.
当应用在后台运行或用户没有与别人聊天时,也应该关闭位置跟踪,也就说说,浏览媒体库,查看朋友列表或调整应用设置时, 都应该关闭位置跟踪

2)只在必要时使用网络

为了提高电量的使用效率, IOS 总是尽可能地保持无线网络关闭.当应用需要建立网络连接时,IOS 会利用这个机会向后台应用分享网络会话,以便一些低优先级能够被处理, 如推送通知,收取电子邮件等

关键在于每当用户建立网络连接时,网络硬件都会在连接完成后多维持几秒的活动时间.每次集中的网络通信都会消耗大量的电量
要想减轻这个问题带来的危害,你的软件需要有所保留的的使用网络.应该定期集中短暂的使用网络,而不是持续的保持着活动的数据流.只有这样,网络硬件才有机会关闭

4.屏幕

屏幕非常耗电, 屏幕越大就越耗电.当然,如果你的应用在前台运行且与用户进行交互,则势必会使用屏幕并消耗电量
这里有一些方案可以优化屏幕的使用:

1)动画优化

当应用在前台时, 使用动画,一旦应用进入了后台,则立即暂停动画.通常来说,你可以通过监听 UIApplicationWillResignActiveNotification或UIApplicationDIdEnterBackgroundNotification的通知事件来暂停或停止动画,也可以通过监听UIApplicationDidBecomeActiveNotification的通知事件来恢复动画

2)视频优化

视频播放期间,最好保持屏幕常量.可以使用UIApplication对象的idleTimerDisabled属性来实现这个目的.一旦设置了 YES, 他会阻止屏幕休眠,从而实现常亮.

与动画类似,你可以通过相应应用的通知来释放和获取锁

用户总是随身携带者手机,所以编写省电的代码就格外重要, 毕竟手机的移动电源并不是随处可见, 在无法降低任务复杂性时, 提供一个对电池电量保持敏感的方案并在适当的时机提示用户, 会让用户体验良好。

四、小

应用安装包大小对应用使用没有影响,但应用的安装包越大,用户下载的门槛越高,特别是在移动网络情况下,用户在下载应用时,对安装包大小的要求更高,因此,减小安装包大小可以让更多用户愿意下载和体验产品。

当然,瘦身和减负虽好,但需要注意瘦身对于项目可维护性的影响,建议根据自身的项目进行技巧的选取。

App安装包是由资源和可执行文件两部分组成,安装包瘦身从以下三部分优化。

资源优化:

1.删除无用的资源

2.删除重复的资源

3.无损压缩图片

4.不常用资源换为下载

编译优化:

1.去除debug符号

2.开启编译优化

3.避免编译多个架构

可执行文件优化:

1.去除无用代码

2.统计库占用,去除无用库

3.混淆类/方法名

4.减少冗余字符串

5.ARC->MRC (一般不到特殊情况不建议这么做,会提高维护成本)

缩减iOS安装包大小是很多中大型APP都要做的事,一般首先会对资源文件下手,压缩图片/音频,去除不必要的资源。这些资源优化做完后,我们还可以尝试对可执行文件进行瘦身,项目越大,可执行文件占用的体积越大,又因为AppStore会对可执行文件加密,导致可执行文件的压缩率低,压缩后可执行文件占整个APP安装包的体积比例大约有80%~90%,还是挺值得优化的。

下面是一些常见的优化方案:

TableViewCell 复用

在cellForRowAtIndexPath:回调的时候只创建实例,快速返回cell,不绑定数据。在willDisplayCell: forRowAtIndexPath:的时候绑定数据(赋值)。

高度缓存

在tableView滑动时,会不断调用heightForRowAtIndexPath:,当cell高度需要自适应时,每次回调都要计算高度,会导致 UI 卡顿。为了避免重复无意义的计算,需要缓存高度。

怎么缓存?

字典,NSCache。

UITableView-FDTemplateLayoutCell

[if !supportLineBreakNewLine]

[endif]

视图层级优化

不要动态创建视图

在内存可控的前提下,缓存subview。

善用hidden。

[if !supportLineBreakNewLine]

[endif]

减少视图层级

减少subviews个数,用layer绘制元素。

少用clearColor,maskToBounds,阴影效果等。

[if !supportLineBreakNewLine]

[endif]

减少多余的绘制操作

图片

不要用JPEG的图片,应当使用PNG图片。

子线程预解码(Decode),主线程直接渲染。因为当image没有Decode,直接赋值给imageView会进行一个Decode操作。

优化图片大小,尽量不要动态缩放(contentMode)。

尽可能将多张图片合成为一张进行显示。

[if !supportLineBreakNewLine]

[endif]

减少透明view

使用透明view会引起blending,在iOS的图形处理中,blending主要指的是混合像素颜色的计算。最直观的例子就是,我们把两个图层叠加在一起,如果第一个图层的透明的,则最终像素的颜色计算需要将第二个图层也考虑进来。这一过程即为Blending。

会导致blending的原因:

UIView的alpha<1。

UIImageView的image含有alpha channel(即使UIImageView的alpha是1,但只要image含有透明通道,则仍会导致blending)。

[if !supportLineBreakNewLine]

[endif]

为什么blending会导致性能的损失?

原因是很直观的,如果一个图层是不透明的,则系统直接显示该图层的颜色即可。而如果图层是透明的,则会引起更多的计算,因为需要把另一个的图层也包括进来,进行混合后的颜色计算。

opaque设置为YES,减少性能消耗,因为GPU将不会做任何合成,而是简单从这个层拷贝。

[if !supportLineBreakNewLine]

[endif]

减少离屏渲染

离屏渲染指的是在图像在绘制到当前屏幕前,需要先进行一次渲染,之后才绘制到当前屏幕。

OpenGL中,GPU屏幕渲染有以下两种方式:

On-Screen

Rendering即当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。

Off-Screen

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

[if !supportLineBreakNewLine]

[endif]

小结

性能优化不是更新一两个版本就可以解决的,是持续性的需求,持续集成迭代反馈。在实际的项目中,在项目刚开始的时候,由于人力和项目完成时间限制,性能优化的优先级比较低,等进入项目投入使用阶段,就需要把优先级提高,但在项目初期,在设计架构方案时,性能优化的点也需要提早考虑进去,这就体现出一个程序员的技术功底了。
什么时候开始有性能优化的需求,往往都是从发现问题开始,然后分析问题原因及背景,进而寻找最优解决方案,最终解决问题,这也是日常工作中常会用到的处理方式。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • iOS开发中UITableview控件的基本使用及性能优化方法

    UITableview控件基本使用 一.一个简单的英雄展示程序 NJHero.h文件代码(字典转模型) 复制代码 代码如下: #import <Foundation/Foundation.h> @interface NJHero : NSObject /**  *  头像  */ @property (nonatomic, copy) NSString *icon; /**  *  名称  */ @property (nonatomic, copy) NSString *name; /**  

  • 详细整理iOS中UITableView的性能优化

    一.介绍 iOS开发中,UITableView可能是平时我们打交道最多的UI控件之一,其重要性不言而喻.Android也是如此,Android中的ListView和UITableView是相同功能的一个控件,但是iOS的UITableView更为强大一点,原因就不说了,如果你学过Android就知道iOS中的UITableView使用起来是非常简单的,这也是峰哥喜欢iOS胜过Android的原因之一.今天研究的内容就是UITableView的优化. 开始之前,你能说出几种UITableView的

  • 详解优化iOS程序性能的25个方法

    1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为你管理retain和release的过程,所以你就不必去手动干预了.忘掉代码段结尾的release简直像记得吃饭一样简单.而ARC会自动在底层为你做这些工作.除了帮你避免内存泄露,ARC还可以帮你提高性能,它能保证释放掉不再需要的对象的内存. 现在所有的iOS程序都用ARC了,这条可以忽略. 2. 在

  • IOS 性能优化中离屏渲染

    GPU屏幕渲染有以下两种方式: On-Screen Rendering 意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行. Off-Screen Rendering 意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作. 特殊的离屏渲染: 如果将不在GPU的当前屏幕缓冲区中进行的渲染都称为离屏渲染,那么就还有另一种特殊的"离屏渲染"方式: CPU渲染. 如果我们重写了drawRect方法,并且使用任何Core Graphics的技术进行了

  • iOS性能优化教程之页面加载速率详解

    前言 我认为在编码过程中时刻注意性能影响是有必要的,但凡事都有个度,不能为了性能耽误了开发进度.在时间紧急的情况下我们往往采用"quick and dirty"的方案来快速出成果,后面再迭代优化,即所谓的敏捷开发.与之相对应的是传统软件开发中的瀑布流开发流程. 卡顿产生的原因 在 iOS 系统中,图像内容展示到屏幕的过程需要 CPU 和 GPU 共同参与.CPU 负责计算显示内容,比如视图的创建.布局计算.图片解码.文本绘制等.随后 CPU 会将计算好的内容提交到 GPU 去,由 GP

  • iOS性能优化浅析

    本文将从原理出发,解释卡顿发生的原理,然后会讲解项目中行之有效的几个优化点,最后会展望一下接下来将要尝试的方向.下面进入正题. 屏幕显示的原理 屏幕显示原理 我们知道,远古时代的CRT显示器的显示原理是用电子枪扫描荧光屏来发光.如上图所示,电子枪按照从左到右,然后从上到下的顺序扫描.当电子枪换到新的一行准备进行扫描时,也就是上图A4.B4.C4.D4的位置,显示器会发出一个水平同步信号:而当一帧画面绘制完成后,电子枪回复到原位准备画下一帧前,也就是上图D4的位置,显示器会发出一个垂直同步信号.垂

  • iOS开发教程之常见的性能优化技巧

    前言 性能问题的主要原因是什么,原因有相同的,也有不同的,但归根到底,不外乎内存使用.代码效率.合适的策略逻辑.代码质量.安装包体积这一类问题. 但从用户体验的角度去思考,当我们置身处地得把自己当做用户去玩一款应用时候,那么都会在意什么呢?假如正在玩一款手游,首先一定不希望玩着玩着突然闪退,然后就是不希望卡顿,其次就是耗电和耗流量不希望太严重,最后就是安装包希望能小一点.简单归类如下: 快:使用时避免出现卡顿,响应速度快,减少用户等待的时间,满足用户期望. 稳:不要在用户使用过程中崩溃和无响应.

  • Python 代码性能优化技巧分享

    如何进行 Python 性能优化,是本文探讨的主要问题.本文会涉及常见的代码优化方法,性能优化工具的使用以及如何诊断代码的性能瓶颈等内容,希望可以给 Python 开发人员一定的参考. Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 80% 的工作量.优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率. 改进算法,选择合适的数据结构 一个

  • iOS 下的图片处理与性能优化详解

    图片在计算机世界中怎样被存储和表示? 图片和其他所有资源一样,在内存中本质上都是0和1的二进制数据,计算机需要将这些原始内容渲染成人眼能观察的图片,反过来,也需要将图片以合适的形式保存在存储器或者在网络上传送. 这种将图片以某种规则进行二进制编码的方式,就是图片的格式. 常见的图片格式 图片的格式有很多种,除了我们熟知的 JPG.PNG.GIF,还有Webp,BMP,TIFF,CDR 等等几十种,用于不同的场景或平台. 这些格式可以分为两大类:有损压缩和无损压缩. 有损压缩:相较于颜色,人眼对光

  • Android编程开发之性能优化技巧总结

    本文详细总结了Android编程开发之性能优化技巧.分享给大家供大家参考,具体如下: 1.http用gzip压缩,设置连接超时时间和响应超时时间 http请求按照业务需求,分为是否可以缓存和不可缓存,那么在无网络的环境中,仍然通过缓存的httpresponse浏览部分数据,实现离线阅读. 2.listview 性能优化 1).复用convertView 在getItemView中,判断convertView是否为空,如果不为空,可复用.如果couvertview中的view需要添加listern

  • 基于JavaScript 性能优化技巧心得(分享)

    JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中.为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择. 本文从加载.上下文.解析.编译.执行和捆绑等多个方面来讲解 JavaScript 的性能优化技巧,以便让更多的前端开发人员掌握这方面知识. 什么是高性能的 JavaScript 代码? 尽管目前没有高性能代码的绝对定义,但却存在一个以用户为中心的性能模型,可以用作参考:RAIL模型. 响应 如果你的应用程序能在1

  • java接口性能优化技巧

    目录 背景 哪些问题会引起接口性能问题 问题解决 慢查询(基于 mysql) ①深度分页 ②未加索引 ③索引失效 ④join 过多 or 子查询过多 ⑤in 的元素过多 ⑥单纯的数据量过大 业务逻辑复杂 ①循环调用 ②顺序调用 线程池设计不合理 锁设计不合理 机器问题(fullGC,机器重启,线程打满) 万金油解决方式 ①缓存 ②回调 or 反查 背景 我负责的系统在去年初就完成了功能上的建设,然后开始进入到推广阶段.随着推广的逐步深入,收到了很多好评的同时也收到了很多对性能的吐槽. 刚刚收到吐

  • Python 性能优化技巧总结

    1.使用测量工具,量化性能才能改进性能,常用的timeit和memory_profiler,此外还有profile.cProfile.hotshot等,memory_profiler用了psutil,所以不能跟踪cpython的扩展: 2.用C来解决费时的处理,c是效率的代名词,也是python用来解决效率问题的主要途径,甚至有时候我都觉得python是c的完美搭档.常用的是Cython,直接把py代码c化然后又能像使用py包一样使用,其次是ctypes,效率最最高的存在,最后还有CPython

  • LAMP服务器性能优化技巧之Linux主机优化

    目前LAMP (Linux + Apache + MySQL + PHP) 近几年来发展迅速,已经成为Web 服务器的事实标准. LAMP这个词的由来最早始于德国杂志"c't Magazine",Michael Kunze在1990年最先把这些项目组合在一起创造了LAMP的缩写字.这些组件虽然并不是开开始就设计为一起使用的,但是,这些开源软件都可以很方便的随时获得并免费获得.这就导致了这些组件经常在一起使用.在过去的几年里,这些组件的兼容性不断完善,在一起的应用情形变得非常普便.为了改

  • Java性能优化技巧汇总

    本文实例汇总了Java性能优化技巧.分享给大家供大家参考.具体分析如下: 这里参考了些书籍,网络资源整理出来,适合于大多数Java应用 在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1.尽量使用final修饰符. 带有final修饰符的类是不可派生的.在JAVA核心API中,有许多应用final的例子,例如java.lang.String.为String类指定final防止了使用者覆盖length()方法.另外,如

  • 值得收藏的20个Linux服务器性能优化技巧

    Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要目的是高效处理非交互式进程,响应时间并不是那么重要,相反,能够长时间处理高负载才是最关键的.Linux高可用服务器集群解决方案让IT系统管理员可以从容应对许多常见的硬件和软件故障,允许多台计算机一起工作,为关键服务正常运行提供保障,系统管理员可以不中断服务执行维护和升级. Linux服务器有各种用途

随机推荐