资讯专栏INFORMATION COLUMN

这可能是最好的性能优化教程(二)

Lin_YT / 1031人阅读

摘要:程序启动过程中那些复杂错误的操作很有可能导致严重的性能问题。系统会根据用户的操作行为调整程序的显示策略,用来提高程序的显示性能。上述操作的任何一个环节出现性能问题都可能导致画面不能及时显示,影响了程序的启动速度。

前言

上篇写了 ArrayMap 和 UI 性能优化,这篇我想和大家聊聊每个人都关心的 APP 启动,参见 Android 性能优化典范。

正文

提高 APP 的启动速度对我们意义深远,很显然,APP 的启动时间越短,使用它的用户越有耐心等待打开这个 APP 进行使用。反之,启动时间太长,用户则有可能还没等到 APP 打开就已经切换到其他 APP 了。

程序启动过程中那些复杂错误的操作很有可能导致严重的性能问题。Android 系统会根据用户的操作行为调整程序的显示策略,用来提高程序的显示性能。例如,一旦用户点击桌面图标,Android 系统会立即显示一个启动窗口,这个窗口会一直保持显示直到画面中的元素成功加载并绘制完第一帧。这种行为常见于程序的冷启动,或者程序的热启动场景(程序从后台被唤起或者从其他 APP 界面切换回来)。

那么关键的问题是,用户很可能会因为从启动窗口到显示画面的过程耗时过长而感到厌烦,从而导致用户没有来得及等程序启动完毕就切换到其他 APP 了。更严重的是,如果启动时间过长,可能导致程序出现 ANR。我们应该避免出现这两种糟糕的情况

从技术角度来说,当用户点击桌面图标开始,系统会立即为这个 APP 创建独立的专属进程,然后显示启动窗口,直到 APP 在自己的进程里面完成了程序的创建以及主线程完成了 Activity 的初始化显示操作,再然后系统进程就会把启动窗口替换成 APP 的显示窗口。

上述流程里面的绝大多数步骤都是由系统控制的,一般来说不会出现什么问题,可是对于启动速度,我们能够控制并且需要特别关注的地方主要有三处:

Activity 的 onCreate 流程,特别是UI的布局与渲染操作,如果布局过于复杂很可能导致严重的启动性能问题。

Application 的 onCreate 流程,对于大型的 APP 来说,通常会在这里做大量的通用组件的初始化操作。

目前有部分 APP 会提供自定义的启动窗口,这里可以做成品牌宣传界面或者是给用户提供一种程序已经启动的视觉效果。

在正式着手解决问题之前,我们需要掌握一套正确测量评估启动性能的方法。所幸的是,Android 系统有提供一些工具来帮助我们定位问题。

有趣的启动时长定位 display time

从 Android KitKat 版本开始,Logcat 中会输出从程序启动到某个 Activity 显示到画面上所花费的时间。这个方法比较适合测量程序的启动时间。

reportFullyDrawn()

我们通常来说会使用异步懒加载的方式来提升程序画面的显示速度,这通常会导致的一个问题是,程序画面已经显示,可是内容却还在加载中。为了衡量这些异步加载资源所耗费的时间,我们可以在异步加载完毕之后调用 activity.reportFullyDrawn() 方法来告诉系统此时的状态,以便获取整个加载的耗时。

Method Tracing

前面两个方法提供了启动耗时的总时间,可是却无法提供具体的耗时细节。为了获取具体的耗时分布情况,我们可以使用 Method Tracing 工具来进行详细的测量。

Systrace

我们可以在 onCreate() 方法里面添加 trace.beginSection()trace.endSection() 方法来声明需要跟踪的起止位置,系统会帮忙统计中间经历过的函数调用耗时,并输出报表。

如果优化 APP 启动速度? 提升 Activity 的创建速度

提升 Activity 的创建速度是优化 APP 启动速度的首要关注目标。从桌面点击 APP 图标启动应用开始,程序会显示一个启动窗口等待 Activity 的创建加载完毕再进行显示。在 Activity 的创建加载过程中,会执行很多的操作,例如设置页面的主题,初始化页面的布局,加载图片,获取网络数据,读写 Preference 等等。


上述操作的任何一个环节出现性能问题都可能导致画面不能及时显示,影响了程序的启动速度。上一个段落我们介绍了使用 Method Tracing 来发现那些耗时占比相对较多的方法。假设我们发现某个方法执行时间过长,接下去就可以使用 Systrace 来帮忙定位到底是什么原因导致那个方法执行时间过长。

除了使用工具进行具体定位分析性能问题之外,以下两点经验可以帮助我们对 Activity 启动做性能优化:

优化布局耗时:一个布局层级越深,里面包含需要加载的元素越多,就会耗费更多的初始化时间。关于布局性能的优化,这里就不展开描述了!

异步延迟加载:一开始只初始化最需要的布局,异步加载图片,非立即需要的组件可以做延迟加载。

别让 Application 初始化不必要的东西

在 Application 初始化的地方做太多繁重的事情是可能导致严重启动性能问题的元凶之一。Application 里面的初始化操作不结束,其他任意的程序操作都无法进行。

有时候,我们会一股脑的把绝大多数全局组件的初始化操作都放在 Application 的 onCreate() 里面,但其实很多组件是需要做区队对待的,有些可以做延迟加载,有些可以放到其他的地方做初始化操作,特别需要留意包含 Disk IO 操作,网络访问等严重耗时的任务,他们会严重阻塞程序的启动。


优化这些问题的解决方案是做延迟加载,可以在 Application 里面做延迟加载,也可以把一些初始化的操作延迟到组件真正被调用到的时候再做加载。

恰当地使用闪屏

启动闪屏不仅仅可以作为品牌宣传页,还能够减轻用户对启动耗时的感知,但是如果使用不恰当,将适得其反。前面介绍过当点击桌面图标启动 APP 的时候,程序会显示一个启动窗口,一直到页面的渲染加载完毕。如果程序的启动速度足够快,我们看的闪屏窗口停留显示的时间则会很短,但是当程序启动速度偏慢的时候,这个启动闪屏可以一定程度上减轻用户等待的焦虑感,避免用户过于轻易的关闭应用。

目前大多数开发者都会通过设置启动窗口主题的方式来替换系统默认的启动窗口,通过这种方式只是使用『障眼法』弱化了用户对启动时间的感知,但本质上并没有对启动速度做什么优化。也有些 APP 通过关闭启动窗口属性 android:windowDisablePreview 的方式来直接移除系统默认的启动窗口,但是这样的弊端是用户从点击桌面图标到真的看到实际页面的这段时间当中,画面没有任何变化,这样的用户体验是十分糟糕的!

对于启动闪屏,正确的使用方法是自定义一张图片,把这张图片通过设置主题的方式显示为启动闪屏,代码执行到主页面的 onCreate() 的时候设置为程序正常的主题。

后记

本篇我们根据胡凯老师总结,解决了启动速度响应,下期我们将带来内存管理章节。
如果想第一时间收到更新信息的可以关注我的简书:简书地址
你也可以选择关注我的公众号:nanchen

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/13909.html

相关文章

  • 可能最好性能优化教程(一)

    摘要:在这样的大背景下,加之我之前写的系列收到较好的反馈,诱导我想出这么一个性能优化系列。性能的目标是减少绘图的等待时间。 本文首发于我的简书:http://www.jianshu.com/p/17fd... 前言 性能检测与分析,一直在 APP 开发中相当重要,但又被我们常常忽略。很多 APP 或者开发者总是急功近利,总想着快速充实 APP 的相关功能,把开发进度放在首位没有问题,可很多...

    klinson 评论0 收藏0
  • 可能最好性能优化教程(三)

    摘要:如果从根源上解决内存泄漏,内存优化必不可少。避免对象的内存泄漏内存对象的泄漏,会导致一些不再使用的对象无法及时释放,这样一方面占用了宝贵的内存空间,很容易导致后续需要分配内存的时候,空闲空间不足而出现。 这可能是最好的性能优化教程系列专栏这可能是最好的性能优化教程(一)这可能是最好的性能优化教程(二)这可能是最好的性能优化教程(三) 前言 内存泄漏从来都是我们老生常谈的话题,无论是 A...

    ad6623 评论0 收藏0
  • Emscripten教程优化代码

    摘要:优化项也会引发一些问题。检查你的代码是否工作并修复问题。从起,及以上的优化级别默认启动了这项设置。目前正在进行改进。代码移植系列文章代码移植主题系列文章是中文站点的一部分内容。 作者:云荒杯倾欢迎加入Wasm和emscripten技术交流群,群聊号码:939206522。 这是关于Emscripten的系列文章,更多文章请看下面链接。 Emscripten代码移植系列文章 Emscr...

    Jokcy 评论0 收藏0
  • Emscripten教程优化代码

    摘要:优化项也会引发一些问题。检查你的代码是否工作并修复问题。从起,及以上的优化级别默认启动了这项设置。目前正在进行改进。代码移植系列文章代码移植主题系列文章是中文站点的一部分内容。 作者:云荒杯倾欢迎加入Wasm和emscripten技术交流群,群聊号码:939206522。 这是关于Emscripten的系列文章,更多文章请看下面链接。 Emscripten代码移植系列文章 Emscr...

    bladefury 评论0 收藏0
  • Flutter教程() 了解Dart语言

    摘要:注如果你想快速的了解以进行开发,中文网有一个语言的资源列表,按照顺序看一遍,相信你就可以直接上手了。最后一些资源资源教程,请访问中文网。 showImg(https://segmentfault.com/img/bV8xQf?w=1020&h=800); 在上一篇教程中说了Flutter使用Dart语言开发。本篇教程整体介绍一下Dart语言,注意,本篇不会介绍Dart具体语法细节,也不...

    Little_XM 评论0 收藏0

发表评论

0条评论

Lin_YT

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<