Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AndroidVitals徹底活用

kr9ly
February 08, 2019

 AndroidVitals徹底活用

kr9ly

February 08, 2019
Tweet

More Decks by kr9ly

Other Decks in Programming

Transcript

  1. Android Vitals徹底活⽤
    Droid Kaigi 2019 Day2 Room3 14:00〜
    @kr9ly(からくり)

    View Slide

  2. ⾃⼰紹介
    Twitter: @kr9ly
    Androidエンジニアだいたい7年⽬くらい(あやふや)
    クラシルという料理動画のアプリ作ってます

    View Slide

  3. みんな⼤好き Google Play

    View Slide

  4. Google PlayはAndroidアプリを
    公開するためのサービス

    View Slide


  5. View Slide

  6. 我々はAndroidアプリを
    公開すること ⾃体 が⽬的ではない

    View Slide

  7. 我々はAndroidアプリを
    公開すること ⾃体 が⽬的ではない
    アプリを公開して
    ユーザーに価値を提供する
    そのためにはアプリの 快適さ が必要不可⽋

    View Slide

  8. Google Playは
    快適な Androidアプリを
    公開するためのサービス

    View Slide

  9. 快適な アプリを提供するために
    Android Vitalsを徹底的に活⽤する

    View Slide

  10. 快適さとは︖

    View Slide

  11. 快適さとは︖
    ユーザーに価値のある体験を提供できること
    致命的にユーザー体験を損ねる体験がないこと
    ⾼いパフォーマンスであること

    View Slide

  12. Android Vitalsでウォッチできるもの
    致命的にユーザー体験を損ねる体験
    クラッシュレート、クラッシュの詳細
    ANRレート、ANRの詳細
    ⾼いパフォーマンス
    起動時間の分布
    レンダリング時間の分布

    View Slide

  13. 致命的にユーザー体験を損ねる体験についての
    指標
    クラッシュ
    ANR

    View Slide

  14. クラッシュレート、クラッシュの詳細
    Crashlyticsとほぼ同じだが、Crashlyticsが初期化される前のクラッシ
    ュも捕捉できる︕(クラシルでも昔あった)

    View Slide

  15. 影響したバージョン、OSの割合、端末の種類、スタックトレース

    View Slide

  16. Proguardの難読化解除
    Proguardで難読化している場合はmapping.txtをちゃんとアップロード
    しておく(⾃動化しとくと楽)

    View Slide

  17. リリース前レポート活⽤してますか︖
    テストトラックで公開すると⾃動テストが⾛る
    クラシルではアルファ版トラックに公開してから本番トラックに公

    View Slide

  18. とりあえずただテストを⾛らせてみるだけでも便利
    それなりにいい感じにアプリ内を巡回してくれる
    アプリのUI構造を解析してからテストしてくれる

    View Slide

  19. RoboScriptでテスト内容を指定できる
    割愛します
    くわしくは https:// rebase.google.com/docs/test-lab/robo-ux-test?
    hl=ja#scripting

    View Slide

  20. 注意点
    実⾏されるまでに結構時間がかかることがある(数時間待つことも
    結構ある)
    リリースのタイミングにも影響するので、ご利⽤は計画的に

    View Slide

  21. リリース前レポート活⽤しよう
    別に限定公開してなくてもテストトラック -> 本番トラックのフローを
    踏むのがおすすめ

    View Slide

  22. ANRの⼀覧
    弊社アプリは起動時がほとんどっぽい…

    View Slide

  23. ANRの詳細
    ANRが発⽣した際(メインスレッドが応答せずに5秒経ったタイミン
    グ)のスレッドダンプが⾒られる

    View Slide

  24. ANR発⽣時点でどの部分を実⾏していたか分かる
    どこでロックを取得しているか分かる(デッドロックになってない
    かも頑張れば分かる)
    なんとなく検討を付ける⼿掛かりになる

    View Slide

  25. パフォーマンス指標
    起動時間の分布
    レンダリング時間の分布

    View Slide

  26. 起動時間の分布
    えっ私のコード遅すぎ…︖(最初に⾒た時の感想)

    View Slide

  27. 起動時間の分布
    起動時間の分布グラフ
    90パーセンタイルの起動時間(下位10パーセントの起動時間)
    99パーセンタイルの起動時間(下位1パーセントの起動時間)
    がわかる

    View Slide

  28. レンダリング時間の分布
    えっ私のコード遅すぎ…︖(⼆回⽬)

    View Slide

  29. レンダリング時間の分布
    レンダリング時間の分布グラフ
    90パーセンタイルのレンダリング時間(下位10パーセントのレンダ
    リング時間)
    99パーセンタイルのレンダリング時間(下位1パーセントのレンダリ
    ング時間)
    がわかる

    View Slide

  30. 遅いなら調べてみましょう
    メソッドトレースを⽣成して調べる
    特定の実⾏期間で実⾏されたコードのスタックトレースと各メソッドの
    実⾏時間が⾒られるスゴイやつ

    View Slide

  31. 最初に注意点
    メソッドトレーシング中は実⾏時間が遅くなる
    絶対値としては実⾏時間は参考にならない
    10秒 -> 5秒とかに縮めても⼤したことないことも

    View Slide

  32. メソッドトレーシングを⾛らせる⽅法
    Android Studioから
    メソッドトレーシングを⾛らせる⽅法
    デバッガを起動する

    View Slide

  33. プロファイラを起動する

    View Slide

  34. Recordボタンを押す

    View Slide

  35. 終わりたくなったらStopで⽌める

    View Slide

  36. この⽅法の利点
    お⼿軽
    コード側をいじる必要が無い
    即座に結果を⾒られる

    View Slide

  37. この⽅法の⽋点
    メソッドトレーシングを開始/終了するタイミングを厳密にいじれな

    起動時のベンチマークには使えない(プロファイラーをアタッチし
    て起動してもトレースをすぐ起動できない)
    1フレームだけ測定するとかできない

    View Slide

  38. コード上からメソッドトレーシングをコントロ
    ールする
    実⾏するメソッドは⼆つ
    android.os.Debug.startMethodTracing
    android.os.Debug.stopMethodTracing

    View Slide

  39. メソッドトレーシングを開始する
    https://developer.android.com/reference/android/os/Debug#startMet
    hodTracing(java.lang.String, int)
    tracePath メソッドトレースのファイル名、分かりやすい名前を付け

    bufferSize トレースファイルの最⼤サイズをバイトで渡す、デフォル
    トだと8MB

    View Slide

  40. 注意点
    bufferSizeは簡単にあふれる
    あふれたら出⼒がそこで途切れてしまうので、
    とりあえず200MBくらいにしておくのがおすすめ
    bufferSizeが⼤きいと出⼒時間が⻑くなるけど気⻑に待つ

    View Slide

  41. (⼩⼀時間ハマりました)

    View Slide

  42. メソッドトレーシングを停⽌する
    https://developer.android.com/reference/android/os/Debug#stopMet
    hodTracing()
    何も難しいことはない

    View Slide

  43. 起動時間を取る場合
    Application.onCreateの先頭でスタート
    public class KurashiruApplication extends Application {
    @Override
    public void onCreate() {
    super.onCreate();
    Debug.startMethodTracing("sample", 200 * 1024 * 1024);
    ...
    }
    }

    View Slide

  44. 最初のフレームの表⽰まで取るのがおすすめ
    public class MainActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    ...
    setContentView(R.layout.activity_main);
    new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
    Debug.stopMethodTracing();
    }
    }, 16);
    ...
    }
    }

    View Slide

  45. 起動時間を⾼速化した例
    起動処理を並列化して対応した事例のご紹介

    View Slide

  46. 改善前
    Viewレンダリング直前までで10秒程度

    View Slide

  47. 注⽬したポイント
    Daggerの初期化処理が遅い(Cognitoの初期化処理が遅い)
    Three-Ten Backportのゾーン情報の初期化が遅い

    View Slide

  48. Daggerの初期化処理が遅い(Cognitoの初期化
    処理が遅い)
    public class EventLogSender {
    private final KinesisFirehoseRecorder recorder;
    @Inject
    public EventLogSender(KinesisFirehoseRecorder recorder) {
    this.recorder = recorder;
    }
    ...
    }
    Injectする際の初期化処理に時間がかかっている

    View Slide

  49. 別にフォアグラウンド上でやる必要はない
    アプリケーションの分析⽤のログ送信処理

    View Slide

  50. Lazyを使う
    public class EventLogSender {
    private final Lazy recorderLazy;
    @Inject
    public EventLogSender(Lazy recorderLazy) {
    this.recorderLazy = recorderLazy;
    }
    public void send() {
    doBackground(() -> {
    recorderLazy.get();
    })
    }
    }

    View Slide

  51. Three-Ten Backportのゾーン情報の初期化が遅い
    例えば
    OffsetDateTime.now() この処理でメインスレッドをブロックされるのはもったいない

    View Slide

  52. バックグラウンドスレッド上で初期化
    public class KurashiruApplication extends Application {
    @Override
    public void onCreate() {
    ...
    doBackground(() -> {
    ZoneId.systemDefault();
    });
    }
    }
    Application.onCreateの先頭でやればある程度の短縮が⾒込める

    View Slide

  53. 改善後
    View初期化まで3秒に短縮

    View Slide

  54. 注意点
    処理がメインスレッド上でしか実⾏できない場合はNG
    スレッドセーフでない処理もNG
    SDKの類が意外とスレッドセーフじゃないもの多いです

    View Slide

  55. レンダリング時間を最適化した際のTips
    スクロールがカクカク状態を解消した時の話ちょっとだけ

    View Slide

  56. トリガーの仕込みがキモ
    public void onScrollChange(RecyclerView recyclerView, int dx, int dy) {
    if (dy > 200) {
    Debug.startMethodTracing("sample", 200 * 1024 * 1024);
    new Handler().postDelayed(() -> {
    Debug.stopMethodTracing();
    }, 16);
    }
    }
    閾値を超えたスワイプを検知したら1フレーム分測定

    View Slide

  57. 意外な処理が遅いことも
    getWindowVisibleDisplayFrame(visibleRect);
    View.getWindowVisibleDisplayFrameが遅かった

    View Slide

  58. ⼤事なこと
    ボトルネックを探す
    ボトルネックを取り除く
    地道にやる

    View Slide

  59. トレース結果を取得する⽅法

    View Slide

  60. トレース結果の出⼒先
    多分 Context.getExternalFilesDir で取得できるディレクトリに出⼒し
    ている
    ⾃分がやったときは
    /sdcard/Android/data/${applicationId}/files
    でした
    詳しくは: https://developer.android.com/studio/pro le/generate-
    trace-logs?hl=ja

    View Slide

  61. Android Vitalsでは
    クラッシュ
    ANR
    起動時間
    レンダリング速度
    をウォッチできる︕

    View Slide

  62. Android Vitalsを徹底的に活⽤して
    快適 なアプリをリリースしよう︕

    View Slide

  63. 実際に改善した︖
    ちょっとだけ…
    快適なアプリへの道のりはつらく険しい

    View Slide

  64. あとはここに⾊々書いてあります
    https://developer.android.com/topic/performance/vitals/
    ⼀読をおすすめ

    View Slide