Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AndroidVitals徹底活用
Search
kr9ly
February 08, 2019
Programming
5
5.5k
AndroidVitals徹底活用
kr9ly
February 08, 2019
Tweet
Share
More Decks by kr9ly
See All by kr9ly
KotlinCoroutinesFlowことはじめ
kr9ly
0
490
あなたがエンジニアリングマネージャーを名乗る理由は何ですか?
kr9ly
0
540
AWS CodeBuild+AWS SAM(Lambda)+Slack で最⾼なAndroid CI環境を作る
kr9ly
0
590
Dagger2を活用してAndroid SDKの依存関係をクリーンにする
kr9ly
8
6.7k
Other Decks in Programming
See All in Programming
Fragment Composition of GraphQL
quramy
4
830
AWS CDKコントリビュートTIPS / aws-cdk-contribution-tips
gotok365
2
140
ONE WEDGE_company_guide
1wedge_one
0
470
効率化に挑戦してみたらモバイル開発が少し快適になった話
ryunakayama
0
130
Java 22 Overview
kishida
1
180
Rethinking UI building strategies @ SFI 2024
letelete
0
270
2 週間で Twitter Bot を作ってみた
contour_gara
0
350
Goのエラースタックトレースの歴史と今後
sonatard
7
1.2k
0→1と1→10の狭間で Javaという技術選定を振り返る/Reflecting on the Decision to Choose Java Between Scaling from 0 to 1 and 1 to 10
jaguar_imo
2
380
AWS Application Composerで始める、 サーバーレスなデータ基盤構築 / 20240406-jawsug-hokuriku-shinkansen
kasacchiful
1
260
R言語の環境構築と基礎 Tokyo.R 112
bob3bob3
0
270
PostmanでAPIの動作確認が楽になった話
h455h1
0
170
Featured
See All Featured
ParisWeb 2013: Learning to Love: Crash Course in Emotional UX Design
dotmariusz
104
6.6k
How to Ace a Technical Interview
jacobian
272
22k
Designing for Performance
lara
601
67k
Stop Working from a Prison Cell
hatefulcrawdad
266
19k
Building a Modern Day E-commerce SEO Strategy
aleyda
17
6.4k
Why Our Code Smells
bkeepers
PRO
331
56k
The Straight Up "How To Draw Better" Workshop
denniskardys
227
130k
YesSQL, Process and Tooling at Scale
rocio
164
13k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.9k
The Pragmatic Product Professional
lauravandoore
25
5.8k
Automating Front-end Workflow
addyosmani
1356
200k
Learning to Love Humans: Emotional Interface Design
aarron
267
39k
Transcript
Android Vitals徹底活⽤ Droid Kaigi 2019 Day2 Room3 14:00〜 @kr9ly(からくり)
⾃⼰紹介 Twitter: @kr9ly Androidエンジニアだいたい7年⽬くらい(あやふや) クラシルという料理動画のアプリ作ってます
みんな⼤好き Google Play
Google PlayはAndroidアプリを 公開するためのサービス
︖
我々はAndroidアプリを 公開すること ⾃体 が⽬的ではない
我々はAndroidアプリを 公開すること ⾃体 が⽬的ではない アプリを公開して ユーザーに価値を提供する そのためにはアプリの 快適さ が必要不可⽋
Google Playは 快適な Androidアプリを 公開するためのサービス
快適な アプリを提供するために Android Vitalsを徹底的に活⽤する
快適さとは︖
快適さとは︖ ユーザーに価値のある体験を提供できること 致命的にユーザー体験を損ねる体験がないこと ⾼いパフォーマンスであること
Android Vitalsでウォッチできるもの 致命的にユーザー体験を損ねる体験 クラッシュレート、クラッシュの詳細 ANRレート、ANRの詳細 ⾼いパフォーマンス 起動時間の分布 レンダリング時間の分布
致命的にユーザー体験を損ねる体験についての 指標 クラッシュ ANR
クラッシュレート、クラッシュの詳細 Crashlyticsとほぼ同じだが、Crashlyticsが初期化される前のクラッシ ュも捕捉できる︕(クラシルでも昔あった)
影響したバージョン、OSの割合、端末の種類、スタックトレース
Proguardの難読化解除 Proguardで難読化している場合はmapping.txtをちゃんとアップロード しておく(⾃動化しとくと楽)
リリース前レポート活⽤してますか︖ テストトラックで公開すると⾃動テストが⾛る クラシルではアルファ版トラックに公開してから本番トラックに公 開
とりあえずただテストを⾛らせてみるだけでも便利 それなりにいい感じにアプリ内を巡回してくれる アプリのUI構造を解析してからテストしてくれる
RoboScriptでテスト内容を指定できる 割愛します くわしくは https:// rebase.google.com/docs/test-lab/robo-ux-test? hl=ja#scripting
注意点 実⾏されるまでに結構時間がかかることがある(数時間待つことも 結構ある) リリースのタイミングにも影響するので、ご利⽤は計画的に
リリース前レポート活⽤しよう 別に限定公開してなくてもテストトラック -> 本番トラックのフローを 踏むのがおすすめ
ANRの⼀覧 弊社アプリは起動時がほとんどっぽい…
ANRの詳細 ANRが発⽣した際(メインスレッドが応答せずに5秒経ったタイミン グ)のスレッドダンプが⾒られる
ANR発⽣時点でどの部分を実⾏していたか分かる どこでロックを取得しているか分かる(デッドロックになってない かも頑張れば分かる) なんとなく検討を付ける⼿掛かりになる
パフォーマンス指標 起動時間の分布 レンダリング時間の分布
起動時間の分布 えっ私のコード遅すぎ…︖(最初に⾒た時の感想)
起動時間の分布 起動時間の分布グラフ 90パーセンタイルの起動時間(下位10パーセントの起動時間) 99パーセンタイルの起動時間(下位1パーセントの起動時間) がわかる
レンダリング時間の分布 えっ私のコード遅すぎ…︖(⼆回⽬)
レンダリング時間の分布 レンダリング時間の分布グラフ 90パーセンタイルのレンダリング時間(下位10パーセントのレンダ リング時間) 99パーセンタイルのレンダリング時間(下位1パーセントのレンダリ ング時間) がわかる
遅いなら調べてみましょう メソッドトレースを⽣成して調べる 特定の実⾏期間で実⾏されたコードのスタックトレースと各メソッドの 実⾏時間が⾒られるスゴイやつ
最初に注意点 メソッドトレーシング中は実⾏時間が遅くなる 絶対値としては実⾏時間は参考にならない 10秒 -> 5秒とかに縮めても⼤したことないことも
メソッドトレーシングを⾛らせる⽅法 Android Studioから メソッドトレーシングを⾛らせる⽅法 デバッガを起動する
プロファイラを起動する
Recordボタンを押す
終わりたくなったらStopで⽌める
この⽅法の利点 お⼿軽 コード側をいじる必要が無い 即座に結果を⾒られる
この⽅法の⽋点 メソッドトレーシングを開始/終了するタイミングを厳密にいじれな い 起動時のベンチマークには使えない(プロファイラーをアタッチし て起動してもトレースをすぐ起動できない) 1フレームだけ測定するとかできない
コード上からメソッドトレーシングをコントロ ールする 実⾏するメソッドは⼆つ android.os.Debug.startMethodTracing android.os.Debug.stopMethodTracing
メソッドトレーシングを開始する https://developer.android.com/reference/android/os/Debug#startMet hodTracing(java.lang.String, int) tracePath メソッドトレースのファイル名、分かりやすい名前を付け る bufferSize トレースファイルの最⼤サイズをバイトで渡す、デフォル トだと8MB
注意点 bufferSizeは簡単にあふれる あふれたら出⼒がそこで途切れてしまうので、 とりあえず200MBくらいにしておくのがおすすめ bufferSizeが⼤きいと出⼒時間が⻑くなるけど気⻑に待つ
(⼩⼀時間ハマりました)
メソッドトレーシングを停⽌する https://developer.android.com/reference/android/os/Debug#stopMet hodTracing() 何も難しいことはない
起動時間を取る場合 Application.onCreateの先頭でスタート public class KurashiruApplication extends Application { @Override public
void onCreate() { super.onCreate(); Debug.startMethodTracing("sample", 200 * 1024 * 1024); ... } }
最初のフレームの表⽰まで取るのがおすすめ 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レンダリング直前までで10秒程度
注⽬したポイント Daggerの初期化処理が遅い(Cognitoの初期化処理が遅い) Three-Ten Backportのゾーン情報の初期化が遅い
Daggerの初期化処理が遅い(Cognitoの初期化 処理が遅い) public class EventLogSender { private final KinesisFirehoseRecorder recorder;
@Inject public EventLogSender(KinesisFirehoseRecorder recorder) { this.recorder = recorder; } ... } Injectする際の初期化処理に時間がかかっている
別にフォアグラウンド上でやる必要はない アプリケーションの分析⽤のログ送信処理
Lazy<T>を使う public class EventLogSender { private final Lazy<KinesisFirehoseRecorder> recorderLazy; @Inject
public EventLogSender(Lazy<KinesisFirehoseRecorder> recorderLazy) { this.recorderLazy = recorderLazy; } public void send() { doBackground(() -> { recorderLazy.get(); }) } }
Three-Ten Backportのゾーン情報の初期化が遅い 例えば OffsetDateTime.now() <- 初回のこれが遅い この処理でメインスレッドをブロックされるのはもったいない
バックグラウンドスレッド上で初期化 public class KurashiruApplication extends Application { @Override public void
onCreate() { ... doBackground(() -> { ZoneId.systemDefault(); }); } } Application.onCreateの先頭でやればある程度の短縮が⾒込める
改善後 View初期化まで3秒に短縮
注意点 処理がメインスレッド上でしか実⾏できない場合はNG スレッドセーフでない処理もNG SDKの類が意外とスレッドセーフじゃないもの多いです
レンダリング時間を最適化した際のTips スクロールがカクカク状態を解消した時の話ちょっとだけ
トリガーの仕込みがキモ 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フレーム分測定
意外な処理が遅いことも getWindowVisibleDisplayFrame(visibleRect); View.getWindowVisibleDisplayFrameが遅かった
⼤事なこと ボトルネックを探す ボトルネックを取り除く 地道にやる
トレース結果を取得する⽅法
トレース結果の出⼒先 多分 Context.getExternalFilesDir で取得できるディレクトリに出⼒し ている ⾃分がやったときは /sdcard/Android/data/${applicationId}/files でした 詳しくは: https://developer.android.com/studio/pro
le/generate- trace-logs?hl=ja
Android Vitalsでは クラッシュ ANR 起動時間 レンダリング速度 をウォッチできる︕
Android Vitalsを徹底的に活⽤して 快適 なアプリをリリースしよう︕
実際に改善した︖ ちょっとだけ… 快適なアプリへの道のりはつらく険しい
あとはここに⾊々書いてあります https://developer.android.com/topic/performance/vitals/ ⼀読をおすすめ