作为一名开发,功能优化是永久绕不过去的论题,在日常的开发中,咱们可肯定都会接触过。Android 的功能优化其实是十分老练的了,老练的套路,老练的方法论,老练的开源结构等等。
对于接触功能优化经历较少的开发者来说,或许很少有机会能去学习或许总结出这些老练的套路,方法论,或许结构。所以作为一位多年长期做功能优化的开发者,在这篇文章中对功能优化的方法论做一些总结,以供大家学习。
功能优化的实质
首要,我先介绍一下功能优化的实质。我对其实质的认知是这样的:功能优化的实质是合理且充沛的运用硬件资源,让程序的体现更好,而且程序体现更好的目的则是为了获取更多来自客户的留存,运用时长,口碑、利润等收益。
所以根据实质来考虑,功能优化最重要的两件工作:
- 合理且充沛的运用硬件资源
- 让程序体现更好,并取得收益
下面讲一下这两件工作。
合理且充沛的运用硬件资源
充沛表明能将硬件的资源充沛发挥出来,但充沛纷歧定是合理的,比方咱们一下子开启了几百个线程,cpu 被充沛发挥了,可是并不合理,所以合理表明所发挥出来的硬件资源能给程序体现有正向的作用。
硬件资源包含:CPU,内存,硬盘,电量,流量(不属于硬件资源,不过也归于需求合理运用的资源之一)等等。
下面举几个合理且充沛的运用硬件资源的比方:
- CPU 资源的运用率高,但并不是过载的状况,而且 cpu 资源首要为当时场景所运用,而不是被运用中各个事务所涣散耗费。比方咱们优化页面翻开速度,速度和 cpu 有很大的联系,那么咱们首要要保证 cpu 被充沛发挥出来了,咱们能够运用多线程、在页面翻开前提早预加载相关资源等策略,来发挥手机的 cpu。可是在翻开页面的时分,咱们要合理的保证 cpu 资源首要被翻开页面相关的逻辑所运用,比方组件创建,数据获取,页面烘托等等,至于其他和当时翻开页面场景联系较少的逻辑,比方周期使命,监控,或许一些预加载等等都能够关闭或许推迟,以此削减非相关使命对 cpu 的耗费,
- 内存资源缓运用充沛,而且又能将 OOM 等异常操控在合理范围内。比方咱们做内存优化,内存优化并不是越少越好,相反内存占用多或许让程序更快,可是内存占用也不能太高,所以咱们能够依据不同层次机型的 OOM 率,将内存的占用操控在充沛运用而且合理的状况,低端机上,经过功能降级等优化,削减内存的运用,高端机上,则能够适当进步内存的占用,让程序体现的更好。
-
……
让程序体现更好,并取得收益
咱们有许多直接的目标来度量功能优化取得的收益,比方做内存优化能够用 pss,java 内存占用,native 内存占用等等;做速度优化,能够用发动速度,页面翻开速度;做卡顿优化,能够用帧率等等。把握这些目标很重要,咱们需求知道怎么能正确而且低功能耗费的监控这些目标数据。
除了上面的直接目标外,咱们还需求了解功能优化的终究体现目标,用户留存率,运用时长,转换率,好评率等目标。有时分,这些目标才是终究度量咱们功能优化作用的数据,比方咱们做内存优化,pss 降低了 100 M,但仅仅只是内存占用少了 100M 并没有太大的收益,假如这个 100M 体现在运用的存活时刻,转化率的进步上,那这 100 M 的优化便是值得的,咱们在向上陈述咱们产出时,也更简单取得认可。
怎么做好功能优化
讲完了功能优化的实质,我再讲讲怎么做好功能优化。我首要从下面这三个方面来解说
- 常识储藏
- 考虑的视点和方法
- 构成完好的闭环
常识储藏
想要做好功能优化,特别是原创性、或许完善而且系统的、或许作用很好的优化,不是咱们从网上看一些文章然后仿照一下就能办到的,需求咱们有比较扎实的常识储藏,然后根据这些常识储藏,经过深化考虑,去剖析咱们的运用,寻觅优化点。我仍然举一些比方,来说明硬件层面,系统层面和软件层面的常识对咱们做好功能优化的协助。
硬件层面
在硬件层面,咱们需求对处理器的系统结构,存储器的层次结构有必定的了解。假如咱们假如不知道 cpu 由几个核组成,哪些是大核,哪些是小核,咱们就不会想到将中心线程绑定大核来进步功能的优化计划;假如咱们不了解存储结构中寄存器,高速缓存,主存的规划,咱们就无法针对这一特性来进步功能,比方将中心数据尽量放在高速缓存中就能进步不少速度相关的功能。
系统层面
对操作系统的了解和了解,也是协助咱们做好功能优化不可缺少的常识。我在这儿列一下系统层面需求把握的常识,但不是全的,Linux的常识包含进程的管理和调度,内存管理,虚拟内存,锁,IPC通讯等。Android系统的常识包含虚拟机,中心服务如ams,wms等等,烘托,以及一些中心流程,如发动,翻开activity,安装等等。
假如咱们不了解Linux系统的进程调度系统,咱们就无法充沛利用进程优先级来协助咱们进步功能;假如咱们不了解 Android 的虚拟机,那么环绕这虚拟机相关的优化,比方 oom 优化,或许是 gc 优化等等都无法很好的开展。
软件层面
软件层面便是咱们自己所开发的 App,在功能优化中,咱们需求对自己所开发的运用尽或许的了解。比方咱们需求知道自己所开发的 App 有哪些线程,都是干嘛的,这些线程的 cpu 耗费状况,内存占用多少,都是哪些事务占用的,缓存命中率多少等等。咱们需求知道自己所开发的 App 有哪些事务,这些运用都是干嘛的,运用率多少,对资源的耗费状况等等。
除了上面说到的三个层面的常识,想要深化做好功能优化,还需求把握更多的常识,比方汇编,编译器、编程言语、逆向等等常识。比方用c++ 写代码就比用java写代码运转更快,咱们能够经过将一些事务替换成 c++ 来进步功能;比方编译期间的内联,无用代码消除等优化能削减包体积;逆向在功能优化上的用途也十分大,经过逆向咱们能够修正系统的逻辑,让程序体现的更好。
能够看到,想要做好功能优化,需求庞大的常识储藏,所以功能优化是很能体现开发者技能深度和广度的,这也是面试时,必定会问功能优化相关的常识的原因。这些常识储藏不是一下就能构成的,需求咱们慢慢的进行学习和堆集。
考虑的视点及方法
讲完了常识储藏,再讲讲考虑的视点和方法。需求留意它和常识储藏没有先后联系,并不是说要有了足够的技能常识后才干开始考虑怎么考虑。考虑的视点和方法体现在咱们开发的所有生命周期中,即使是新入门的开发,也能够训练自己从不同的视点和方法去进行考虑。下面就聊一聊我在做功能优化的过程中,在考虑的视点和方法上的一些认知。为了让大家能更形象的理解,我就都以发动优化来解说。
考虑视点
我这儿首要经过运用层,系统词,硬件层这三个视点来介绍我对发动速度优化的考虑。
运用层
做发动速度优化时,假如从运用层来考虑,我会根据事务的维度考虑所加载的事务的运用率,必要性等等,然后拟定优先级,在发动的时分只加载首屏运用,或许运用率高的事务。所以接着我就能够规划发动结构用来管理使命,发动结构要规划好优先级,而且能对这些初始化的使命有运用率或许其他功能方面的计算,比方这些使命初始化后,被运用率的概率是多少,又或许初始化之后,对事务的体现进步提现在哪,协助有多大。
从运用层的考虑首要是根据对事务的管控或许对事务进行优化来进步功能。
系统层
以及系统层来考虑发动优化也有许多点,比方线程和线程优先级维度,在发动过程中,怎么操控好线程数量,怎么进步主线程的优先级,怎么削减发动过程中不相关的线程,比方 gc 线程等等。
硬件层
从硬件层来考虑发动优化,咱们能够从 cpu 的利用率,高速缓存cache的命中率等维度来考虑优化。
除了上面说到的这几个视点,咱们还能够有更多视点。比方跳出本设备之外来考虑,是否能够用其他的设备协助咱们加快发动。google play 就有类似的优化,gp会上传一些其他机器已经编译好的机器码,然后相同的设备下载这个运用时,也会带着这些编译好的机器码一同下载。还有很常用的服务端烘托技能,也是让服务端线烘托好界面,然后直接暂时静态模块来进步页面翻开速度;又或许站在用户的视点去考虑,想一想到底什么样的优化对用户感知上是有好处的,比方有时分咱们再做发动或许页面翻开速度优化,会给用户一个假的静态页面让用户感知已经翻开了,然后再去绑定真实的数据。
做功能优化时,考虑的视点多一些,全面一些,能协助咱们想出更多的优化计划。
考虑方法
除了训练咱们站在不同的视点考虑问题,咱们还能够训练自己考虑问题的方法,这儿介绍自上而下和自下而上两种考虑方法。
自上而下
咱们做发动优化,自上而下的优化思路或许是直接从发动出发,然后剖析发动过程中的链路,然后寻觅耗时函数,将耗时函数放子线程或许懒加载处理,可是这种方法会导致优化做的不全面。比方将耗时的使命都放在子线程,咱们再高端机上速度确实变快了,可是在低端机上,或许会降低了发动速度,由于低端机的 cpu 很差,线程一多,导致 cpu 满载,主线程反而获取不到运转时刻。其次,假如从上层来看,一个函数履行耗时久或许并不是这个函数的问题,也或许是由于该函数长时刻没有获取到 cpu 时刻。
自上而下的考虑很简单让咱们疏忽实质,导致优化的作用不明显或许不完好。
自下而上
自下而上考虑便是从底层开始考虑,还是以发动优化为比方,自下而上的考虑就不是直接剖析发动链路,寻觅慢函数,而是直接想着怎么在发动过程中合理且充沛的运用 cpu 资源,这个时分咱们的计划就许多了,比方咱们或许会想到不同的机型 cpu 能力是纷歧样的,所以咱们会针对高端机和低端机来分别优化,高端机上,咱们想办法让cpu利用率更高,低端机上想办法防止 cpu 的超载,同时配合慢函数,线程,锁等常识进行优化,就能拟定一套系统而且完好的发动优化计划。
完好的闭环
上面讲的都是怎么进行优化,优化很重要,但并不是悉数,在实践的功能优化中,咱们需求做的有监控,优化,防劣化,数据收益搜集等等,这些部分都做好才干构成一个完好的闭环。我一一讲一下这几个部分:
- 监控:完好的监控运用中各项功能的目标,仅仅有目标监控是不够的,咱们还需求尽量做归因的监控。比方内存监控,咱们不仅仅要监控咱们运用的内存目标,还能够还要能监控到各个事务的内存运用占比,大集合,大图片,大对象等等归因项。而且咱们的监控同样要根据功能考虑去规划。完好的监控能让咱们更高效的发现和处理异常。
- 优化:优化便是前面说到的,合理且充沛的运用硬件资源,让程序的体现更好。
- 防劣化:防劣化也是有许多工作能够做的,包含建立完善的线下功能测验,线上监控的报警等。比方内存,咱们能够在线下每天经过monkey跑内存泄露并提早治理,这便是防劣化。
-
数据收益搜集。学会用好A/B测验,学会关注中心价值的目标。比方咱们做内存优化,一味的追求降低运用内存的占用并不是最优,内存占用的多,或许会让咱们的程序运转更快,用户体验更好,所以咱们需求结合崩溃率,留存等等这种体验中心价值的目标,来确定内存到底要不要继续进行优化或许优化到多少。
小结
上面便是我在多年的功能优化经历中总结出来的认知及方法论。只要了解了这些方法论,咱们才干在进行功能优化时,如虎添翼,游刃有余。
这篇文章也没有介绍具体的优化计划,由于功能优化的计划经过一篇文章是介绍不完的,大家有兴趣能够看看我写的小册《Android 功能优化》,能够系统的学一学怎么进行优化,上面解说的方法论,也都会在这本小册中体现出来。