APP性能优化

一、性能问题分类

  1. 渲染问题:过度绘制,布局冗杂
  2. 内存问题:内存管理,内存泄漏
  3. 功耗问题:耗电管理

二、性能优化原则和方法

     原则:

  1. 使用各种性能工具测试,快速定位问题
  2. 使用低配置设备:相同的问题一般在低配置的暴露出来的问题会更多
  3. 得在完成功能需求的前提下优化,不可以本末倒置

     方法:

  1. 了解问题,首先分为可感知和不可感知,比如卡片的滑动卡顿--这是可感知的,内存泄漏,层级冗杂---这是不可感知的
  2. 定位问题,可感知的问题大多数心中有数,可以随时更改,不可感知的问题就需要用工具监测,分析数据,定位在什么地方存折性能问题
  3. 分析问题,确定解决方案
  4. 验证问题,保证优化有效,没有产生新的问题,产品的稳定性

三、性能优化工具

    以下优化工具在下面文章中具体介绍使用方法,

  1. 手机开发者选项:调试GPU过度绘制、启用严格模式、显示CPU使用情况、GPU呈现模式分析、显示所有应用程序无响应
  2. IDE中:Android Studio,比如静态代码监测工具、Memory Monitor 、CPU Monitor、NetWork Monitor、GPU Monitor 、LayoutInspector、Analyze APK
  3. SDK中:sdk\tools、比如DDMSHierarchyViewer、TraceView
  4. 第三方工具:MAT、LeakCanary、GT等

四、性能优化指标

   1、渲染

  • 滑动流畅度:FPS,即Frame Per Second,一秒内刷新帧数,基本上是接近60帧最好
  • 过度绘制:单页面的3X(粉红色区域)Overdraw小于25%
  • 启动时间:主要说的是activity界面启动时间,一般少于300ms,用高频摄像机计算时间

   2、内存

  • 内存大小:峰值越低越好,优化前后做对比
  • 内存泄漏:需要用工具检查对比优化前后

   3、功耗

    尽可能少用电

--------------------------------------------------------------------------------------------------------------------

一、渲染问题

  造成应用UI卡顿的常见原因都有哪些?

  1. 认为在UI线程做耗时操作
  2. 布局xml过于复杂,无法在16ms中完成渲染
  3. 同一时间动画执行次数过多,导致CPU或GPU负载过重
  4. View过度绘制,导致某些像素在同一帧内被多次绘制,从而使CPU或GPU负载过重
  5. View频繁触发measure layout方法,导致其累计耗时过多,整个View频繁重新渲染
  6. 内存频繁触发GC过多(同一帧内频繁创建内存),导致暂时阻塞渲染操作
  7. 冗余资源及逻辑等导致加载和执行缓慢;
  8. anr

Google说大多数用户感觉到的卡顿等性能问题主要是因为渲染性能,Android 系统每隔16ms发出VSYNC信号(vertical synchronization  场扫描同步,场同步,垂直同步),触发对UI进行渲染 ,如果每次渲染都成功,就能达到流畅的画面所需要的60FPS,为了能够实现60FPS,就得要求程序的大多数操作都必须在16ms(1000/60=16.67ms)内完成。

     如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。

APP性能优化_第1张图片

1、过度绘制:同一帧的时间内,屏幕上的某些像素点被绘制了多次,在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源,找出界面滑动不流畅、界面启动速度慢、手机发热。

如何查看过度绘制?----设置 — 开发中选项 — 调试GPU过度绘制

APP性能优化_第2张图片

上图中的各种颜色都代表什么意思?

APP性能优化_第3张图片

 

优化方法和步骤关键总结:

  1. 移除或修改Window默认的Background
  2. 移除XML布局文件中非必需的Backgroun
  3. 按需显示占位背景图片
  4. 控制绘制区域

2、布局优化

  1. 可以使用相对布局减少层级的就使用相对布局,否则使用线性布局。Android中RelativeLayout和LinearLayout性能分析
  2. 用merge标签来合并布局,这可以减少布局层次
  3. 用include标签来重用布局,抽取通用的布局可以让布局的逻辑更清晰明了,但要避免include乱用
  4. 避免创建不必要的布局层级。(最容易发生的!
  5. 使用惰性控件ViewStub实现布局动态加载,

    这个标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。
    通常情况下我们需要在某个条件下使用某个布局的时候会通过gone或者invisible来隐藏,其实这样的方式虽然隐藏了布局,但是当显示该界面的时候还是将该布局实例化的。使用ViewStub可以避免内存的浪费,加快渲染速度。
    其实ViewStub就是一个宽高都为0的一个View,它默认是不可见的,只有通过调用setVisibility函数或者Inflate函数才会将其要装载的目标布局给加载出来,从而达到延迟加载的效果,这个要被加载的布局通过android:layout属性来设置。

3、查看渲染性能的工具

  •     CPU呈现模式分析        开发者选项 — GPU呈现模式分析 — 选择“在屏幕上显示为条形图”Android开发者选项—GPU呈现模式分析
  • GPU Monitor   
  •  APP性能优化_第4张图片

 

 

二、内存问题

        1、内存浪费,程序内存的管理是否合理高效对应用的性能有着很大的影响。推荐阅读Android性能优化典范-第3季

          ①:多使用ArrayMap,少使用HashMap,Android为移动操作系统特意编写了一些更加高效的容器,

             例如ArrayMap、SparseArray。为了解决HashMap更占内存的弊端,Android提供了内存效率更高的ArrayMap,

               这俩差别是什么?HashMap在使用时,它会一次性开辟确定数量的内存存储空间,根据Key来排,如果没有对应的key来填充,这块空间就空着,存储其他东西的时候不会补到这里,(我现在说不清楚,等我再学学,弄明白了再写);

               ArrayMap正好相反:它是有多少key,存多少hash 代号(开辟多少),存的时候是记录指向key,value的地址,当我们想要获取某个value的时候,ArrayMap会计算输入可以转换过后的hash值,然后对应hash数组使用二分法去查找对应的index,然后通过这个index在另外一个数组中直接访问到对应的键值对,ArrayMap的占用内存是连续不间断的,那么他是如何处理插入和删除的操作的,

APP性能优化_第5张图片APP性能优化_第6张图片

我没看懂 ,等我弄明白这里。。再写

反正就是ArrayMap和HashMap之间占用内存对比来说,HashMap比ArrayMap多几十倍,

②:Autoboxing  避免自动装箱,类似HashMap这样的容器中增删改查的时候发生了大量的Autoboxing,当key是int类型的时候,HashMap和ArrayMap都会发生Autoboxing行为

③:少用Enum,它会大大增加编译后文件

 

推荐一些文章:

  • HashMap,ArrayMap,SparseArray源码分析及性能对比,参考:http://www.jianshu.com/p/7b9a1b386265#

  • Android性能优化--小心自动装箱:http://blog.csdn.net/lgz_ei/article/details/69208784

  • Android性能优化篇:Android中如何避免创建不必要的对象:http://blog.csdn.net/jia635/article/details/52525243

  • HashMap、ArrayMap、SparseArray分析比较:http://blog.csdn.net/chen_lifeng/article/details/52057427

  • Android性能优化之String篇:http://www.androidchina.net/5940.html

  • SharedPreferences的commit和apply分析:http://blog.csdn.net/u010198148/article/details/51706483

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(APP性能优化)