App 有哪些自身原因导致卡顿?

另外本文需要比较熟悉 Systrace,这个我其实个人也就了解个皮毛,但是还是值得深入的,后续会加入学习计划。

在 Android 中的卡顿丢帧原因概述 - 系统篇

https://www.androidperformance.com/2019/09/05/Android-Jank-Due-To-System/

这篇文章中我们列举了系统自身原因导致的手机卡顿问题 , 这一篇文章我们主要列举一些由于 App 自身原因导致的卡顿问题. 各位用户在使用 App 的时候 , 如果遇见卡顿现象 , 先别第一时间骂手机厂商优化烂 , 先想想是不是这个 App 自己的问题。

Android 手机使用中的卡顿问题 , 一般来说手机厂商和 App 开发商都会非常重视 , 所以不管是手机厂商还是 App 开发者 , 都会对卡顿问题非常重视 , 内部一般也会有专门的基础组或者优化组来进行优化 .

目前市面上有一些非常棒的第三方性能监控工具 , 比如腾讯的 Matrix ;

https://github.com/Tencent/matrix

手机厂商一般也会有自己的性能监控方案 , 由于可以修改源码和避免权限问题 , 所以手机厂商可以拿到更多的数据 , 分析起来也会更方便一些.

说回流畅度 , 其实就是操作过程中的丢帧 , 本来一秒中画面需要更新 60 帧,但是如果这期间只更新了 55 帧 , 那么在用户看来就是丢帧了 , 主观感觉就是卡了 , 尤其是帧率波动 , 用户的感知会更明显. 引起丢帧的原因非常多, 有硬件层面的 , 有软件层面的 , 也有 App 自身的问题. 所以这一部分我分为四篇文章去讲 , 会简单讲一下哪些原因会用户觉得卡顿丢帧 :

  1. Android 中的卡顿丢帧原因概述 - 方法论

    https://www.androidperformance.com/2019/09/05/Android-Jank-Debug/

  2. Android 中的卡顿丢帧原因概述 - 系统篇

    https://www.androidperformance.com/2019/09/05/Android-Jank-Due-To-System/

  3. Android 中的卡顿丢帧原因概述 - 应用篇

    https://www.androidperformance.com/2019/09/05/Android-Jank-Due-To-App/

  4. Android 中的卡顿丢帧原因概述 - 低内存篇 https://www.androidperformance.com/2019/09/18/Android-Jank-Due-To-Low-Memory/

这一篇文章我们主要列举一些由于 App 自身原因导致的卡顿问题. 各位用户在使用 App 的时候 , 如果遇见卡顿现象 , 先别第一时间骂手机厂商优化烂 , 先想想是不是这个 App 自己的问题.

这些实际的案例 , 很多都可以在 Systrace 上看出来 , 所以我的很多贴图都是 Systrace 上实际被发现的问题 , 如果你对 Systrace 不了解 , 可以查看这个 Systrace 系列。

https://www.androidperformance.com/2019/05/26/Android_Systrace_0/

这里你只需要知道 , Systrace 从系统全局的角度 , 来展示当前系统的运行状况 , 通常被用来 Debug Android 性能问题 .

1

App 主线程执行时间长

主线程执行 Input Animation Measure Layout Draw decodeBitmap 等操作超时都会导致卡顿 , 下面就是一些真实的案例

Measure Layout 耗时超时 (或者没有调度到)

Draw 耗时

Animation 回调耗时

View 初始化耗时 (PlayStore)

List Item 初始化耗时(WeChat)

decodeBitmap 耗时 (或者没有调度到)

2

uploadBitmap 耗时

这里的 uploadBitmap 主要是 upload bitmap to gpu 的操作 , 如果 bitmap 过大 , 或者每一帧内容都在变化 , 那么就需要频繁 upload , 导致渲染线程耗时.

3

BuildDrawingCache 耗时

应用本身频繁调用 buildDrawingCache 会导致主线程执行耗时从而导致卡顿 , 从下图来看, 主线程每一帧明显超过了 Vsync 周期

微信对话框有多个动态表情的时候, 也会出现这种情况导致的卡顿

4

使用 CPU 渲染而不是 GPU 渲染

如果应用在 Activity 中设置了软件渲染, 那么就不会走 hwui , 直接走 skia, 纯 cpu 进程渲染, 由于这么做会加重 UI Thread 的负载, 所以大部分情况下这种写法都会导致卡顿 , 详细技术分析可以看这篇文章 Android 中的 Hardware Layer 详解

https://www.androidperformance.com/2019/07/27/Android-Hardware-Layer/

5

主线程 Binder 耗时

Activity resume 的时候, 与 AMS 通信要持有 AMS 锁, 这时候如果碰到后台比较繁忙的时候, 等锁操作就会比较耗时, 导致部分场景因为这个卡顿, 比如多任务手势操作

6

游戏 SurfaceView 内容绘制不均匀

这一项指的是游戏自身的绘制问题, 会导致总是不能满帧去跑, 如下图, 红框部分是 SurfaceFlinger 显示掉帧, 原因是底下的游戏在绘制的时候, 刚好这一帧超过了 Vsync SF 的信号.这种一般是游戏自身的问题.

7

WebView 性能不足

应用里面涉及到 WebView 的时候, 如果页面比较复杂, WebView 的性能就会比较差, 从而造成卡顿

8

帧率与刷新率不匹配

如果屏幕帧率和系统的 fps 不相符 , 那么有可能会导致画面不是那么顺畅. 比如使用 90 Hz 的屏幕搭配 60 fps 的动画

9

应用性能跟不上高帧率屏幕和系统

部分应用由于设计比较复杂, 每一帧绘制的耗时都比较长 , 这么做的话在 60 fps 的机器上可能没有问题 , 但是在 90 fps 的机器上就会很卡, 因为从 60 -> 90 , 每帧留给应用的绘制时间从 16.6 ms 变成了 11.1 ms , 如果没有在 11.1 ms 内完成, 就会出现掉帧的情况.

如下图, 这个 App 的性能比较差, 每一帧耗时都很长

10

主线程 IO 操作

主线程操作数据库使用 SharedPerforence 的 Commit 而不是 Apply

11

WebView 与主线程交互

与 WebView 进行交互的时候, 如果 WebView 出现问题, 那么也会出现卡顿

微信文章页卡顿

12

RenderThread 耗时

RenderThread 自身比较耗时, 导致一帧的时长超过 Vsync 间隔.

渲染线程耗时过长阻塞了主线程的下一次 sync

13

多个 RenderThread 同步导致主线程卡顿

有的 App 会产生多个 RenderThread ,在某些场景下 RenderThread 在 sync 的时候花费比较多的时间,导致主线程卡顿

adb shell ps -AT | grep10300| grepRenderThread

u0_a17 0103001622867092693260305172SyS_epoll_wait 0S RenderThread

u0_a17 0103001739467092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001739567092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001739667092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001739767092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001739967092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001740067092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001740167092693260305172futex_wait_queue_me 0S RenderThread

u0_a17 0103001740267092693260305172futex_wait_queue_me 0S RenderThread

14

总结

Android 原生系统是一个不断进化的过程 , 目前已经进化到了 Android Q , 每个版本都会解决非常多的性能问题 , 同时也会引进一些问题 ; 到了手机厂商这里 , 由于硬件差异和软件定制 , 会在系统中加入大量的自己的代码 , 这无疑也会影响系统的性能 . 同样由于 Android 的开放 , App 的质量和行为也影响着整机的用户体验.

本篇主要列出了 App 自身的实现问题导致的流畅性问题 , Android App 最大的问题就是质量良莠不齐 , 不同于 App Store 这样的强力管理市场 , Android App 不仅可以在 Google Play 上面进行安装 , 也可以在其他的软件市场上面安装 , 甚至可以下载安装包自行安装 , 可以说上架的门槛非常低 , 那么质量就只能由 App 开发者自己来把握了.

许多大厂的 App 质量自然不必多说 , 他们对性能和用户体验都是非常关注的 , 但也会有需求和功能过多导致的性能问题 , 比如微信就非常占内存 ; 新版本的 QQ 要比之前版本的使用起来流畅性差好多 .

中小厂的 App 就更不用说了. 再加上 Android 平台的开放性 , 需要 App 玩起来黑科技 , 什么保活 相互唤醒 热更新 跑后台任务等 . 站在 App 开发者的角度来说这无可厚非 , 但是系统开发者则希望系统能在用户使用的时候 , 前后台 App 都能有正常的行为 , 来保证前台 App 的用户体验 . 也希望 App 开发者能重视自己 App 的性能体验 , 给用户一个好印象.

系统这边发现 App 自身的性能问题 , 且在其他厂商的手机上也是一样的表现的时候 , 通常会与 App 开发者进行联系 , 沟通一起解决 .返回搜狐,查看更多

阅读 ()
平台声明
该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。