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.8k
AndroidVitals徹底活用
kr9ly
February 08, 2019
Tweet
Share
More Decks by kr9ly
See All by kr9ly
KotlinCoroutinesFlowことはじめ
kr9ly
0
510
あなたがエンジニアリングマネージャーを名乗る理由は何ですか?
kr9ly
0
590
AWS CodeBuild+AWS SAM(Lambda)+Slack で最⾼なAndroid CI環境を作る
kr9ly
0
690
Dagger2を活用してAndroid SDKの依存関係をクリーンにする
kr9ly
8
7.1k
Other Decks in Programming
See All in Programming
とにかくAWS GameDay!AWSは世界の共通言語! / Anyway, AWS GameDay! AWS is the world's lingua franca!
seike460
PRO
1
800
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
4
1.1k
Quine, Polyglot, 良いコード
qnighy
4
630
C++でシェーダを書く
fadis
6
4k
イベント駆動で成長して委員会
happymana
1
300
EventSourcingの理想と現実
wenas
6
2.2k
Jakarta EE meets AI
ivargrimstad
0
310
Generative AI Use Cases JP (略称:GenU)奮闘記
hideg
0
220
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
170
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
3
430
Importmapを使ったJavaScriptの 読み込みとブラウザアドオンの影響
swamp09
4
1.3k
Macとオーディオ再生 2024/11/02
yusukeito
0
340
Featured
See All Featured
A Philosophy of Restraint
colly
203
16k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
For a Future-Friendly Web
brad_frost
175
9.4k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
Statistics for Hackers
jakevdp
796
220k
YesSQL, Process and Tooling at Scale
rocio
168
14k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Code Reviewing Like a Champion
maltzj
520
39k
The World Runs on Bad Software
bkeepers
PRO
65
11k
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/ ⼀読をおすすめ