原文链接:http://blog.nimbledroid.com/2015/09/17/how-to-make-your-application-fluid.html
Nimbledroid.com 为您开发的应用的每一版本提供自动全面的性能分析
正文
在上一篇发布的博客中,我们讨论了监视app性能的重要性。这一回我们将要想大家详细展示怎样具体操作。我们和一些世界著名app的开发团队(其中包括微信和雅虎新闻聚合的团队)就开发流畅的app所需的最好的开发规范进行过交谈。就我们的经验和同那些开发团队的Leader交谈的结果来看,我们发现开发好的app最重要的规范是建立一套app优化流程:
优化过程
持续地监测你的app的性能来检测你的app是否表现不佳是非常重要的。一旦一项性能问题被检测到,你应当集中精力去寻找问题的根源。这项诊断也许需要更多的检测和优化具体性能的数据,这会使你陷入一个我们所谓的“检测—分析 循环”的陷阱相当长的时间。即使在你搜寻到问题的根源后,仅仅修改好懒散的代码是远不够的。你必须重估你app的度量以确保你的修改奏效。这就意味着更多的检测。
检测
主要影响用户体验的性能度量有两种。第一种,我们主要关注响应时间:你的app对一个用户操作(比如:app的启动,看一篇新的文章,加载一个联系人列表,或者是查看一个Facebook也页面)的响应需要多长时间。理想情况下,你的app对以上这些情景响应都很迅速,这会使得你的app有更好,更吸引人的用户体验。
关于响应时间的一个关键(并且独特)的例子是启动时间。app启动时间是一个用户对一款app的第一印象,而第一印象是非常重要的。事实上,一项计算机软件调查显示79%的用户会在删除这个问题app之前再次尝试一或两次。
以下是在软件性能和优化方面有很多年经验的NimbleDroid所给的一些建议。
我们建议你的app应当在2秒之内完成启动,因为这是用户所期待启动时间的中等水平。对于那些对web性能优化很熟悉的人,47%的用户希望一个页面在2秒以内加载完毕,用户对于他们使用活跃的移动app更缺少耐心。
建议 1:显示app启动时间在2秒以内
第二重要的度量是流畅度。app在短时间内响应是很好的体验,但响应同时必须流畅,尽量少的卡顿。用户非常善于察觉卡顿,这也意味着即使微小的卡顿也会对你的app用户体验有负面影响。一般来说,人类可以察觉22毫秒的卡顿,其中1/4的人可以洞察2毫秒—16毫秒的卡顿 — 即标准的60帧每秒的刷新率(FPS)。
要理解流畅度,你可以通过收集你的app的FPS和每帧耗时的数据。然而,你需要牢记:这些数据并不能告诉你app性能问题的根源,也不能帮你找出代码里导致卡顿的方法。
对于Android手机,UI线程(你的app执行的主线程)是唯一能更新UI的线程。为了保持60FPS的刷新率,UI线程必须在16毫秒内完成每帧的绘制。如果UI线程里任何方法的调用耗时比这更长,你的app就会丢失一帧,造成短暂的卡顿。更糟糕的是在这段时间里,你的app对用户的任何操作是不响应的因为UI线程被一个方法的调用给阻塞了。
按照常规来说,要想保证UI线程里每次的方法调用都在16毫秒以内几乎是不可能的。32毫秒是一个临界值,相当于丢掉2帧,也更加真是。我们把那些执行时间超过这个临界值(超过32毫秒执行的)方法称之为耗时方法,因为这些方法导致了这个app暂时“挂起”了。剔除所有耗时方法可以有效地使你的app表现更加流畅,整体上提供一个更好的用户体验。
建议 2:剔除耗时方法
好吧。检测那些和用户体验有关的度量非常重要,但是我们检测这些度量的频率是多少呢?每次构建的时候检测?还是每天构建的时候?或是发布之前?或是版本在生产环境中?!你应该一有机会就检测 — 你越是频繁地追踪你软件的度量,你就越早地能察觉和对性能问题做出反应。雅虎的团队告诉我们在每次他们的app发布前都有分析,微信的团队每天构建的时候都分析他们的app。
建议 3:尽可能频繁地检测
分析
优化你的软件的关键是了解常见的性能问题的和系统地在你的代码中移除他们。在我们对app下载超过5M的文件时的性能问题分析中,我们发现开发者经常使用那些在桌面机器上执行很快却在性能较弱的移动设备上执行非常慢的构造方法。例如:在一台Macbook Air上ClassLoader.getResourceAsStream()这个方法获取一个有3K大小的jar包资源花费7毫秒执行完毕。然而2013年的Nexus 7 在同样资源文件的情况下执行该方法需要1700毫秒。原因是Android对getResourceAsStream这个方法的实现在第一次执行的时候干了很多额外的工作,对apk文件中所有资源文件进行了索引,验证授权的apk文件,解析它的manifest文件。类似这类的操作很耗费CPU资源,导致app明显减速,— getResourceAsStream使Walgreens大约减速1.7倍。NimbleDroid编了一个在你的app中可以避免这种情况的方法列表。你可以在这查看。
建议 4:了解一系列的常见问题
有时候性能问题是由你使用的第三方的SDK而不是你的代码导致的。这些问题往往很难被追踪到。考虑到 org.joda.time是一个很流行的处理时间的java库。你很可能在你以往的Java工程中用到了它。结果表明仅仅在app启动的时候创建一个org.joda.time.DateTime()对象会导致启动言重变慢 — Yahoo Fantasy Sports这款app会启动慢2秒。这是因为org.joda.time.DateTime()使用了getResourceAsStream()这个方法来从apk文件中加载时区数据。
建议 5:避免第三方SDK所导致的意外
优化
修改懒散的代码可以是一个噩梦般的经历。造成app减缓、停止运行的方法有很多,排除这些问题可能会花费几周的开发时间。与此同时,也有一些通用的修改建议。你可以一方面用更多高效的数据展现形式、算法和实现来使代码运行地更快,或者(在那些引用第三方SDK不能直接修改代码的情况下)你可以调用子线程的代码以确保UI不会等待。遵循这些建议会使你在让app更加高效,创造用户喜爱的产品的道路上走得更远。
你能得到帮助的地方
通常需要宝贵的时间和一些灵感来使这个性能优化过程帮助你打造更加流畅的app。这就是我们提供给Android开发者快速,强大的优化分析工具的原因,以保证这些开发者可以更集中精力于你们所擅长的方面:给用户带来美妙的产品。