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
6.1k
AndroidVitals徹底活用
kr9ly
February 08, 2019
Tweet
Share
More Decks by kr9ly
See All by kr9ly
KotlinCoroutinesFlowことはじめ
kr9ly
0
560
あなたがエンジニアリングマネージャーを名乗る理由は何ですか?
kr9ly
0
640
AWS CodeBuild+AWS SAM(Lambda)+Slack で最⾼なAndroid CI環境を作る
kr9ly
0
740
Dagger2を活用してAndroid SDKの依存関係をクリーンにする
kr9ly
8
7.4k
Other Decks in Programming
See All in Programming
NPOでのDevinの活用
codeforeveryone
0
850
Advanced Micro Frontends: Multi Version/ Framework Scenarios @WAD 2025, Berlin
manfredsteyer
PRO
0
180
PHPでWebSocketサーバーを実装しよう2025
kubotak
0
290
Systèmes distribués, pour le meilleur et pour le pire - BreizhCamp 2025 - Conférence
slecache
0
120
プロダクト志向ってなんなんだろうね
righttouch
PRO
0
190
코딩 에이전트 체크리스트: Claude Code ver.
nacyot
0
550
Goで作る、開発・CI環境
sin392
0
240
ペアプロ × 生成AI 現場での実践と課題について / generative-ai-in-pair-programming
codmoninc
2
18k
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
130
MDN Web Docs に日本語翻訳でコントリビュートしたくなる
ohmori_yusuke
1
130
dbt民主化とLLMによる開発ブースト ~ AI Readyな分析サイクルを目指して ~
yoshyum
3
1k
AI駆動のマルチエージェントによる業務フロー自動化の設計と実践
h_okkah
0
170
Featured
See All Featured
A better future with KSS
kneath
238
17k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
510
The World Runs on Bad Software
bkeepers
PRO
69
11k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.7k
Gamification - CAS2011
davidbonilla
81
5.4k
Designing for Performance
lara
610
69k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
24k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.5k
The Straight Up "How To Draw Better" Workshop
denniskardys
235
140k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Code Review Best Practice
trishagee
69
19k
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/ ⼀読をおすすめ