Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
AndroidVitals徹底活用
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
kr9ly
February 08, 2019
Programming
6.5k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AndroidVitals徹底活用
kr9ly
February 08, 2019
More Decks by kr9ly
See All by kr9ly
KotlinCoroutinesFlowことはじめ
kr9ly
0
610
あなたがエンジニアリングマネージャーを名乗る理由は何ですか?
kr9ly
0
690
AWS CodeBuild+AWS SAM(Lambda)+Slack で最⾼なAndroid CI環境を作る
kr9ly
0
800
Dagger2を活用してAndroid SDKの依存関係をクリーンにする
kr9ly
8
7.8k
Other Decks in Programming
See All in Programming
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
110
How I Stole PSI from Android Studio - DroidKaigi2026
worker8
0
130
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
420
Building an Out-of-Order CPU
latte72
1
780
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
460
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
1.2k
速習iPhone Duo対応
yuukiw00w
1
510
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
4
690
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.4k
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
220
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
390
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
120
Featured
See All Featured
Scaling GitHub
holman
464
140k
The Curse of the Amulet
leimatthew05
3
14k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Accessibility Awareness
sabderemane
1
210
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
A better future with KSS
kneath
240
18k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
280
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
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/ ⼀読をおすすめ