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
6k
AndroidVitals徹底活用
kr9ly
February 08, 2019
Tweet
Share
More Decks by kr9ly
See All by kr9ly
KotlinCoroutinesFlowことはじめ
kr9ly
0
540
あなたがエンジニアリングマネージャーを名乗る理由は何ですか?
kr9ly
0
620
AWS CodeBuild+AWS SAM(Lambda)+Slack で最⾼なAndroid CI環境を作る
kr9ly
0
730
Dagger2を活用してAndroid SDKの依存関係をクリーンにする
kr9ly
8
7.3k
Other Decks in Programming
See All in Programming
設計の本質:コード、システム、そして組織へ / The Essence of Design: To Code, Systems, and Organizations
nrslib
4
630
AIコーディングエージェントを 「使いこなす」ための実践知と現在地 in ログラス / How to Use AI Coding Agent in Loglass
rkaga
3
520
VitestのIn-Source Testingが便利
taro28
6
2.1k
DataStoreをテストする
mkeeda
0
290
エンジニアが挑む、限界までの越境
nealle
1
240
Agentic Applications with Symfony
el_stoffel
2
310
小田原でみんなで一句詠みたいな #phpcon_odawara
stefafafan
0
340
API for docs
soutaro
2
1.4k
サービスレベルを管理してアジャイルを加速しよう!! / slm-accelerate-agility
tomoyakitaura
1
190
Fiber Scheduler vs. General-Purpose Parallel Client
hayaokimura
1
110
「”誤った使い方をすることが困難”な設計」で良いコードの基礎を固めよう / phpcon-odawara-2025
taniguhey
0
160
gen_statem - OTP's Unsung Hero
whatyouhide
1
210
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
60k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Become a Pro
speakerdeck
PRO
27
5.3k
4 Signs Your Business is Dying
shpigford
183
22k
Done Done
chrislema
183
16k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
GraphQLとの向き合い方2022年版
quramy
46
14k
Faster Mobile Websites
deanohume
306
31k
YesSQL, Process and Tooling at Scale
rocio
172
14k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
A Modern Web Designer's Workflow
chriscoyier
693
190k
How to Ace a Technical Interview
jacobian
276
23k
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/ ⼀読をおすすめ