性能优化

2020-07-28  本文已影响0人  厚积方能薄发

Android 需要注意的性能优化点

谈谈你做过的性能优化

我所做的优化主要是以下几个方面:

  1. 启动优化
  2. 绘制优化
  3. 内存优化
  4. 稳定性优化
  5. Hybrid 优化

启动优化:

首先你得知道这块是不是需要优化,这个主要通过2个途径:

  1. 直观感觉启动时间是不是过于长,是否有卡顿或白屏的感觉
  2. 监控应用的启动时间:我的方法是监控从 Application onCreate 方法第1行开始监控,到第1个 Activity onResume 方法执行完成时所用的时间。
    怎样去优化:
    在应用开发中往往会加载很多的第三方库,而这些库往往是需要在应用启动时初始化的,有的是在 Application 启动的时候初始化,有的是在首个 Activity 启动的时候初始化。我们需要做的就是尽可能减少该部分的耗时,能 delay 启动的可以 delay 一下,如果不可以的话做一些异步化,减少主线程的时间占用。

绘制优化:

绘制优化总体来说就是卡顿优化,也就是减少应用的卡顿感,使我们感受到卡顿感的场景有以下几种,UI 的刷新绘制、页面的跳转、事件的响应。
而引起卡顿感的因素又分为以下几个方面:

  1. 界面绘制层级深、页面复杂、刷新不合理。
  2. 数据处理:导致这种卡顿有以下几个场景:
    1. 数据处理在 UI 线程
    2. 数据处理占用 CPU 高,导致主线程拿不到时间片
    3. 内存增加导致 GC 频繁
      检测方法:
  1. 减少代码层级
  2. 减少同一层级控件数量。
  3. 一个控件的属性越少,解析越愉快,删除控件中的无用属性。
  4. 如果层级相同 LinearLayout 要优于 RelativeLayout,因为 RL 会对子 View 做2次测量。
  5. 如果 LinearLayout 有 weight 属性,也需要2次测量,但由于没有依赖关系,仍然比 RL 的效率高。
  6. ViewStub 提高显示速度,如果某个布局中多个元素可能只会显示一部分,而另一部分不会显示,应该选用 ViwStub,它可以实现延迟加载布局布局。
  7. 尽量少用 wrap_content,它会增加布局的计算成本,如果已知宽度为固定值时,尽量写固定值。
  8. 使用 <merge/> 标签减少布局嵌套层级。

内存优化:

内存导致卡顿原因:
为了整个系统的内存控制需要,Android 系统为每一个应用程序都设置一个硬性的 Dalvik Heap Size 最大限制阈值,这个阈值在不同的设备上会因为 RAM 的大小不同而有所差异,如果应用占用内存空间已经接近这个阈值时,再尝试分配内存的话,就很容易引起 OOM 错误。 如果到达临界值时,系统会进行 GC 操作,如果占用内存经常在阈值徘徊的话,会导致频繁 GC ,就会引起卡顿。

内存泄漏:
指应用中不会再使用的对象,但垃圾回收时没有辨认出来,不能及时回收。
场景:

  1. 资源性对象未关闭
  2. 注册对象未注销
  3. 静态变量持有大数据对象
  4. 非静态内部类的静态实例
  5. Handler 导致内存泄漏
  6. 容器中的对象没有清理造成内存泄漏
  7. WebView
    检测工具:LeakCanary、Android Profiler

优化方法:

  1. AutoBoxing
  2. 内存复用(系统资源、ListView item 复用、对象池、bitmap)
  3. 使用最优的数据类型
  4. 少用枚举类型
  5. 图片内存优化

稳定性优化:

稳定性优化,主要是减少 crash 和 ANR
监控:
可以自己监控也可以交给第3方平台来监控,现在很多平台都可以做到该功能(有盟、百度统计、腾讯Bugly)。
这个有很多的第三方工具都可以帮助监控,我们公司用的是腾讯的 Bulgy,它可以同时监控到 Java 层和 Native 层的 Crash。

ANR 发生的原因:

Hybrid 优化:

首先了解网页渲染需要做的工作:

  1. 下载 html、css、js
  2. 渲染 DOM、CSS
  3. 执行 JS
  4. 下载图片
    缺点:流程比较繁琐,而且速度较慢。

优化:
整体逻辑:资源离线包化。

  1. 首先走浏览器缓存。
  2. 服务端将资源打包成 zip 包,并加密处理,上传到 CDN。
  3. 客户端也会将一部分不会改变的资源直接打到 apk 中,请求的时候会首先找 apk 内的包,没有的话再找离线包。
  4. 客户端在启动页面,通过请求服务端接口下发离线包的版本号来控制是否升级新的离线包。
  5. 将启动页面和 WebView 页面放到同一个页面,这样起到一个预加载的作用。
  6. 图片懒加载
  7. 并添加调试功能,可动态关闭离线功能。

优化后在主流机型测试性能提升 80% 左右。

遇到的问题:

问题1:首页会打包到apk中,并用 file 协议请求,但跨域请求失败。
原因:
如果服务端不允许跨域,则浏览器会驳回请求,无法读取服务端数据,导致 Ajax 跨域失败。
Webview 设置 setAllowUniversalAccessFromFileURLs(true) 以允许 file 协议的页面内部可以向其他源发起 http/https 请求。

问题2:区分正式与测试环境
客户端在 url 参数后面加测试环境和正式环境的标识。

问题3:4.4版本的未用离线包资源
发现 shouldInterceptRequest 这个方法是区别于不同版本的,需要同时监控2个方法。

上一篇下一篇

猜你喜欢

热点阅读