Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

みんな⼤好き Google Play

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

快適さとは︖

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

プロファイラを起動する

Slide 34

Slide 34 text

Recordボタンを押す

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

この⽅法の⽋点 メソッドトレーシングを開始/終了するタイミングを厳密にいじれな い 起動時のベンチマークには使えない(プロファイラーをアタッチし て起動してもトレースをすぐ起動できない) 1フレームだけ測定するとかできない

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

メソッドトレーシングを開始する https://developer.android.com/reference/android/os/Debug#startMet hodTracing(java.lang.String, int) tracePath メソッドトレースのファイル名、分かりやすい名前を付け る bufferSize トレースファイルの最⼤サイズをバイトで渡す、デフォル トだと8MB

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

最初のフレームの表⽰まで取るのがおすすめ 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); ... } }

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

トリガーの仕込みがキモ 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フレーム分測定

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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