Android App性能评测分析-启动时间篇

简介: 1、前言随着项目版本的迭代,App的性能问题会逐渐暴露出来,而好的用户体验与性能表现紧密相关,性能问题从应用的启动优化开始,下面会根据实际app性能测试案例,进行app性能评测之启动时间的分析和总结。

1、前言

随着项目版本的迭代,App的性能问题会逐渐暴露出来,而好的用户体验与性能表现紧密相关,性能问题从应用的启动优化开始,下面会根据实际app性能测试案例,进行app性能评测之启动时间的分析和总结。

2、App启动方式了解

通常来说, 一个App启动也会分如下三中不同的状态:

  • 冷启动
    当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动,也就是先实例化Application

    冷启动的流程即为App启动流程的全过程, 需要创建App进程, 加载相关资源, 启动Main Thread, 初始化首屏Activity等.

    在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至首屏Activity完全启动.

    下图展示了冷启动的时间线:


    冷启动流程.png
  • 热启动
    当启动应用时,后台已有该应用的进程,这时会从已有的进程来启动Activity(不需要重新创建Application)

    类同与冷启动, 在这个过程中, 屏幕会显示一个空白的窗口(颜色基于主题), 直至activity渲染完毕.

  • 温启动
    介于冷启动和热启动之间, 一般来说在以下两种情况下发生:

    • 用户back退出了App, 然后又启动. App进程可能还在运行, 但是activity需要重建.

    • 用户退出App后, 系统可能由于内存原因将App杀死, 进程和activity都需要重启, 但是可以在onCreate中将被动杀死锁保存的状态(saved instance state)恢复.

通过三种启动状态的相关描述, 可以看出我们要做的启动优化其实就是针对冷启动. 热启动和温启动都相对较快.

3、性能评测结果案例分析

3.1 XX银行 APP启动时间评测结果分析

3.1.1 启动时间测试结果

统计的时间为APP的冷启动时间,4G网络情况下,平均冷启动时间为14.1S,平均热启动时间为6.7S,无网络时平均启动时间为5.2S。由于APP的启动时间耗时远远超过行业标准水平3S,当app启动时,任何一个地方有耗时操作都会拖慢我们应用的启动速度,所以针对APP启动时间做了具体分析

3.1.2评测结果分析

首先来看App从点击桌面图标到我们看到App的主界面整个过程中经过了哪些步骤:
启动虚拟机—>启动AMS —>通过Zygote创建ApplicationProcess进程–>Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。

1)初始化Application
  • 【初始化Application】应用程序初始化总共耗费了3.26S,耗时已超过行业APP启动标准基线时间3S。具体看下耗时详情分析:
    (1)应用Application.attach的时间较长。应用存在多个dex文件,请控制应用方法数量。
    (2)onCreate方法耗时长,主要体现BaseApplication创建上。

长耗时方法排名如下:
1.com.pingan.fstandard.framework.base.BaseApplication.onCreate(BaseApplication.java)

  1. com.pingan.fstandard.common.c.a(InitManager.java)
  2. com.pafinancialtech.pafs.kitchendaddy.f.b(PAFFToast.java:83
    4.com.pingan.fstandard.HomeApplication.d(HomeApplication.java:51

综上分析,BaseApplication创建上耗费较长时间,需要开发进行更详细的分析优化。另外,初始化Application时,也包含了任意门相关等非核心功能的程序,建议启动时不创建该类程序。

2)初始化Activity
  • 【初始化Activity】耗时也过长,耗时约1s左右
    主要耗时的地方是在闪屏界面创建oncreate时com.pingan.fstandard.activity.SplashActivity.onCreate,建议开发优化
3)加载请求及响应

首先来一张流程图了解一下我们APP首页加载的一个流程

页面加载流程.png
冷启动资源加载.png
  • 【网络请求及响应】总体来看,首页加载耗时占比最多,需要6s左右,对应的网络消耗时间占比45%左右。

根据抓包及代码段分析显示APP启动到首页加载完成是一个预加载和异步加载的过程。
(1) 项目中大部分第三方组件都抢占先机,在Application主线程初始化。这样的初始化方式肯定是过重的,建议考虑异步初始化三方组件,不阻塞主线程;延迟部分三方组件(比如埋点统计、任意门、ImageLoader的初始化)。
(2) 启动到首页加载完成网络请求密集,请求内容丰富,部分资源重复请求
请求了相关配置信息、启动页广告、个推、磁贴配置信息、商城理财产品列表,运营广告Banner、F后端接口,广告BANNER位、插件信息、任意门、百度地图SDK(talkingdata、灰度升级)等林林总总加起来就有40+个网络请求,加载的数据+广告页一共有1.7M左右,这说明了我们的APP首页设计的内容比较丰富,部分资源重复请求,部分内容需要调外部接口,所以耗时比较长,这是产品设计问题、信息未做缓存处理和部分外部关联方接口响应慢的原因导致,建议优化。
(3)非核心功能资源过早请求加载
另外其中类似百度地图SDK、任意门、微信sdk相关插件只有在生活页\分享时使用到的非主要业务功能启动时也加载出来了,建议开发同学和产品同学调整APP启动时网络请求的加载策略,非核心/主要/高PV的功能相关的API,SDK、插件等没有必要在启动时做加载缓存,这是非常耗时且得不偿失的。

3.1.3启动时间优化建议

(1)应用Application.attach的时间较长。应用存在多个dex文件,请控制应用方法数量。
(2)onCreate方法耗时长,主要体现BaseApplication创建上,需要开发进行更详细的分析优化,建议考虑异步初始化三方组件,不阻塞主线程;延迟或者和产品一起梳理需要的去除的部分三方组件(比如统计、任意门、ImageLoader的初始化)。
(3)com.pingan.fstandard.activity.MainActivity存在过度绘制导致卡顿,首页UI布局层次过多,建议开发进一步分析优化
(4)建议产品调整优化app启动时网络请求的加载策略,非核心/主要/高PV的功能相关的API,SDK、插件等没有必要在启动时做加载缓存
(5)部分资源重复请求,建议信息缓存,常用信息只在第一次获取,之后从缓存中取
(6)建议开发梳理无用但被执行的老代码,去掉无用但被执行的老代码

综上,建议开发童鞋尽快投入做APP启动时性能改善和优化,以提升行业相比竞品的竞争力。

4、App端启动耗时排查方法及思路

4.1 排查方法:使用Traceview分析

TraceView 是 Android SDK 中内置的1个工具,它可以加载 trace 文件,用图形的情势展现代码的履行时间、次数及调用栈,便于我们分析。

(1)使用Android Studio工具DDMS

生成Traceview 进行分析查看具体Trace期间各方法调用关系,调用次数以及耗时比例


ddms.png

(2)使用代码生成 trace 文件

  Debug.startMethodTracing("shixintrace");   
 //开始 trace,保存文件到 "/sdcard/shixintrace.trace"
    // ...
    Debug.stopMethodTracing();    //结束

代码很简单,当你调用开始代码的时候,系统会生产 trace 文件,并且产生追踪数据,当你调用结束代码时,会将追踪数据写入到 trace 文件中。
下1步使用 adb 命令将 trace 文件导出到电脑:

adb pull /sdcard/shixintrace.trace /tmp

使用代码生成 trace 方式的好处是容易控制追踪的开始和结束,缺点就是步骤略微多了一点。

(3)直接使用android studio生成trace文件

Android Studio 内置的 Android Monitor 可以很方便的生成 trace 文件到电脑。
注意:此方法仅仅适用于下拉代码到本地生成DEBUG测试包到手机进行调试


monitor1.png
monitor2.png

分析指标:

不应在Application以及Activity的生命周期回调中做任何费时操作,具体指标大概是你在onCreate,onResume,onStart等回调中所花费的总时间最好不要超过400ms,否则用户在桌面点击你的应用图标后,将感觉到明显的卡顿。

4.2 开启严苛模式(StrictMode)

检查是否有主线程做了耗时操作: 开启 严苛模式(StrictMode)

(1)StrictMode可以用于捕捉发生在应用程序 主线程中耗时的磁盘、网络访问或函数调用,使主线程处理UI和动画在磁盘读写和网络操作时变得更平滑,避免主线程被阻塞,导致ANR窗口的发生。

下面是启用StrictMode的实例,可以在Application的OnCreate中添加,这样就能在程序启动的最初一刻进行监控了。

private void setStrictMode() {
        if (Integer.valueOf(Build.VERSION.SDK) > 3) {
            Log.d(LOG_TAG, "Enabling StrictMode policy over Sample application");
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()    // 这里可以替换为.detectDiskReads().detectDiskWrites().detectNetwork()。
                                    // detectAll() 包括了磁盘读写和网络I/O
                    .penaltyLog()   //打印logcat,当然也可以定位到dropbox,通过文件保存相应的log
                    .penaltyDeath()
                    .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
        }
    }

(2)除了通过日志查看之外,我们也可以在开发者选项中开启严格模式,开启之后,如果主线程中有执行时间长的操作,屏幕则会闪烁,这是一个更加直接的方法。

4.3、通过抓包工具分析

可以通过抓包工具Charels、Fiddler等查看网络请求加载了哪些资源,加载资源的顺序、哪些资源重复加载、信息是否缓存

4.4、查看Logcat

通过adb输出log信息,过滤日志查看APP启动时每个方法的大致耗时。

4.5、启动时间排查思路

对于App来说, 我们可以控制的启动时间线的点无外乎:

Application的onCreate
首屏Activity的渲染

而我们现在的App动不动集成了很多第三方服务, 启动时需要检查广告, 注册状态等等一系列接口都是在Application的onCreate或是首屏的onCreate中做的.

5、启动时间耗时常见原因及优化建议

5.1、 常见主要问题(持续补充ing)

  • 部分数据库及IO的操作发生在首屏Activity主线程;
  • Application中创建了线程池;
  • 启动时做密集沉重的初始化(Heavy app initialization);
  • Multidex的使用,也是拖慢启动速度的元凶;
  • UI存在过度绘制;
  • 首屏Activity网络请求密集;
  • 非核心功能资源过早请求加载
  • 工作线程使用未设置优先级;
  • 信息未缓存,重复获取同样信息;
  • 流程问题:例如闪屏图每次下载,当次使用;
  • 执行无用老代码;
  • 执行开发阶段使用的代码;
  • 执行重复逻辑;
  • 调用三方SDK里或者Demo里的多余代码;

5.2、建议:

  • 去掉无用但被执行的老代码;
  • 去掉开发阶段使用但线上被执行的代码;
  • 去掉重复逻辑执行代码;
  • UI渲染优化,去除重复绘制,减少UI重复绘制时间
  • 去掉调用三方SDK里或者Demo里的多余代码;
  • 信息缓存,常用信息只在第一次获取,之后从缓存中取;
  • 项目是多进程架构,只在主进程执行Application的onCreate();
  • 根据优先级的划分,一些初始化工作能否将任务优先级划分成3个等级,任务优先级为2,3的,通过懒加载的方式在首页渲染完成后进行加载
  • 避免I/O操作、反序列化、网络操作、布局嵌套等。

参考文献:
学习地址:
https://www.cnblogs.com/sunzn/p/3192231.html
http://www.wfuyu.com/technology/27625.html
http://blog.csdn.net/qq_16131393/article/details/51172488

目录
相关文章
|
2月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
202 4
|
2月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
6天前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
|
1月前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
32 8
|
3月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
93 15
Android 系统缓存扫描与清理方法分析
|
2月前
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
43 1
|
2月前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
3月前
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
Android底层:通熟易懂分析binder:1.binder准备工作
|
4月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
162 3
|
3月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。