Slide 1

Slide 1 text

起動時間で差をつけろ! 
 アプリ起動パフォーマンス改善! 
 yanmar

Slide 2

Slide 2 text

自己紹介 yanmar - 所属:チャリチャリ株式会社 (Charichari, Inc.) - 職種:Androidチームリード兼テックリード - 経歴: 2018.03 早稲田大学商学部 卒 2018.04~ 東京海上日動火災保険 2020.01~ レンサ 2022.05~ フラー 2024.02~ チャリチャリ 2

Slide 3

Slide 3 text

アジェンダ Agenda 1 . アプリの起動時間とは
 What is application startup time? 2 . パフォーマンス検査
   Performance Inspection 3 . パフォーマンス向上
   Performance Improvements 4 . パフォーマンスモニタリング
   Performance Monitoring 3

Slide 4

Slide 4 text

アプリの起動時間とは 
 What is application startup time? 4

Slide 5

Slide 5 text

起動の方法 Ways to launch ・コールドスタート
  Cold start ・ウォームスタート
  Warm start ・ホットスタート
  Hot start 5

Slide 6

Slide 6 text

コールドスタート Cold start ・デバイスの起動後に初めてアプリを起動
  Launch the app for the first time after device  activation ・システムがアプリを強制終了した後で起動
  Launch after the system has killed the  application ※ アプリキルからの起動 ⊂ コールドスタート
 Booting from app kill is part of the cold start
 6

Slide 7

Slide 7 text

ウォームスタート Warm start ・アプリを終了 → 再び起動(プロセスは生きている)
  Exit application -> Start again (process is still running) ・メモリからアプリを削除 → 再び起動(状態バンドル  利⽤可)
  Remove app from memory -> Start again (state  bundle available) 7

Slide 8

Slide 8 text

ホットスタート Hot start ・アプリのプロセスがバックグラウンドで実行されて
  いる場合
  If the app process is still running in the background すべてのアクティビティがまだメモリに存在していれば初期 化処理を行わなくて良いため、高速起動できる
 Fast startup if all activity still exists in memory
 8

Slide 9

Slide 9 text

起動の方法 Ways to launch 参照:さまざまな起動状態とそれぞれのプロセスを⽰した図 https://developer.android.com/topic/performance/vitals/launch-time?hl=ja#hot 9

Slide 10

Slide 10 text

・TTID (Time To Initial Display) - 初期表示までの時間
 - プロセスの初期化〜最初のフレーム表示
 Process initialization - first frame generation 起動時間の指標 Startup time index ・TTFD (Time To Full Display) - 完全表示までの時間
 - コンテンツが表示され、ユーザー操作できるまで
 Time until content is displayed and can be manipulated by the user 10

Slide 11

Slide 11 text

起動時間の指標 Startup time index 11

Slide 12

Slide 12 text

パフォーマンス検査 
 Performance Inspection 12

Slide 13

Slide 13 text

前提 Assumption 計測はReleaseビルドで行う Measure with Release build 本番アプリでの改善が目的であり
 環境を一致させなければ意味がない
 The goal is to improve on the production application, and if the environment does not match, there is no point. 13

Slide 14

Slide 14 text

パフォーマンス検査  Performance Inspection ・Macrobenchmark - アプリ操作によって直接アプリを制御して計測 Direct app control and measurement by app operation - スクロールやアニメーションの計測にも使える It can be used to measure scrolling and animation.    → 定期的な観測で、不要な変更が入っていないか確認できる    Regular observation to check for unwanted changes. 14

Slide 15

Slide 15 text

パフォーマンス検査  Performance Inspection ・CPU Profiler - ボトルネックの特定とパフォーマンス問題の追跡 Identify bottlenecks and track performance issues - Android Studio内で完結 Complete within Android Studio    → どこの処理で時間がかかっているのかが視覚的にわかる    Visual indication of where the process is taking time 15

Slide 16

Slide 16 text

16 Macrobenchmark

Slide 17

Slide 17 text

buildTypes { release { isMinifyEnabled = false isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } create("benchmark") { initWith(buildTypes.getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") isDebuggable = false } } 17 Macrobenchmark

Slide 18

Slide 18 text

@RunWith(AndroidJUnit4::class) class ExampleStartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = "com.example.performance", metrics = listOf(StartupTimingMetric()), iterations = 10, startupMode = StartupMode.COLD ) { pressHome() startActivityAndWait() } } 18 Macrobenchmark

Slide 19

Slide 19 text

19 Macrobenchmark

Slide 20

Slide 20 text

Macrobenchmark Activity.reportFullyDrawn() UIが完全に描画され、重要なデータが反映されたタイミング で呼び出す
 Call when the UI is fully drawn and important data is reflected 20

Slide 21

Slide 21 text

CPU Profiler 起動時間計測のための設定 
 Configuration for 
 startup time measurement 
 Tool Bar ↓ Run ↓ Edit Configurations 21

Slide 22

Slide 22 text

CPU Profiler app ↓ Profiling ↓ Check Start this recording on startup ↓ CPU activity Java/Kotlin Method Sample 22

Slide 23

Slide 23 text

CPU Profiler ・Profile 'app' with low overhead:CPU、メモリプロファイラー
  CPU and Memory profilers ・Profile 'app' with complete data:CPU、メモリ、エネルギープロファイラー
  CPU, Memory, and Energy profilers. 23

Slide 24

Slide 24 text

CPU Profiler 24

Slide 25

Slide 25 text

CPU Profiler 25

Slide 26

Slide 26 text

パフォーマンス向上 
 Performance Improvements 26

Slide 27

Slide 27 text

ツールとライブラリ Tools & Libraries 1 . App Startupライブラリ
   App Startup Library 2 . ベースラインプロファイル
   Baseline Profiles 3 . 起動プロファイル
   Startup Profiles 27

Slide 28

Slide 28 text

App Startup アプリ起動時のコンポーネント初期化ライブラリ
 Component initialization library at app startup ・単一のコンテンツプロバイダで複数のInitializer共有ができる
  Multiple Initializer shares with a single content provider ・初期化の順序を制御できる
  Can control the order of initialization 28

Slide 29

Slide 29 text

App Startup 󰢏 ContentProviderでの個別初期化 → App Startup
  Initialization with ContentProvider → App Startup 󰢃 Applicationクラスでの初期化 → App Startup   Initialization in Application class → App Startup App Startupで起動時間改善するには... 
 To improve startup time with App Startup... 29

Slide 30

Slide 30 text

App Startup 30

Slide 31

Slide 31 text

App Startup 自動初期化の無効化 Disable automatic initialization 31

Slide 32

Slide 32 text

App Startup dependencies { implementation "androidx.startup:startup-runtime:1.1.1" } build.gradle class ExampleInitializer : Initializer { override fun create(context: Context) { // initialization process } override fun dependencies(): List>> { // No dependencies on other libraries. return emptyList() } } ExampleInitializer.kt 32

Slide 33

Slide 33 text

App Startup AndroidManifest.kt 33

Slide 34

Slide 34 text

ベースラインプロファイル Baseline Profiles 起動や画面遷移、スクロールなど重要な機能を提供するガイド 
 Guide role in providing important functions such as startup, screen transitions, scrolling, etc. 1 . 主要な起動パスや重要なメソッドを含むプロファイルを生成
   Generate a profile containing the main launch paths and   important methods for your app 2 . APKにプロファイルを埋め込む
   Embed profiles in APKs 3 . ART(Android runtime)による最適化
   Optimization by ART (Android runtime) 34

Slide 35

Slide 35 text

ベースラインプロファイル Baseline Profiles 35

Slide 36

Slide 36 text

ベースラインプロファイル Baseline Profiles 36

Slide 37

Slide 37 text

ベースラインプロファイル Baseline Profiles @RunWith(AndroidJUnit4::class) @LargeTest class BaselineProfileGenerator { @get:Rule val rule = BaselineProfileRule() @Test fun generate() { rule.collect( packageName = InstrumentationRegistry.getArguments().getString("targetAppId") ?: throw Exception("targetAppId not passed as instrumentation runner arg"), includeInStartupProfile = true ) { pressHome() startActivityAndWait() } } } 37

Slide 38

Slide 38 text

ベースラインプロファイル Baseline Profiles 38

Slide 39

Slide 39 text

起動プロファイル Startup Profiles 参照:DEX レイアウトからのコードの局所性の改善 https://developer.android.com/topic/performance/baselineprofiles/dex-layout-optimizations?hl=ja 39

Slide 40

Slide 40 text

起動プロファイル Startup Profiles isMinifyEnabled = true baselineProfile { dexLayoutOptimization = true } build.gradle Settings 40

Slide 41

Slide 41 text

起動プロファイル Startup Profiles @RunWith(AndroidJUnit4::class) @LargeTest class BaselineProfileGenerator { @get:Rule val rule = BaselineProfileRule() @Test fun generate() { rule.collect( packageName = InstrumentationRegistry.getArguments().getString("targetAppId") ?: throw Exception("targetAppId not passed as instrumentation runner arg"), includeInStartupProfile = true ) { Generator Settings ※ 起動フローでのみ使用すること 
  To be used only in the startup flow 
 41

Slide 42

Slide 42 text

起動プロファイル Startup Profiles @Test fun generate() { rule.collect( packageName = InstrumentationRegistry .getArguments() .getString("targetAppId") ?: throw Exception("targetAppId not passed as instrumentation runner arg"), includeInStartupProfile = true ) { pressHome() startActivityAndWait(Intent().apply { setPackage(packageName) setAction("com.example.app.NEWS_FEED") }) } } Generator Settings 42

Slide 43

Slide 43 text

起動プロファイル Startup Profiles 43

Slide 44

Slide 44 text

プロファイル Profiles @Test fun startupCompilationNone() = benchmark(CompilationMode.None()) @Test fun startupCompilationBaselineProfiles() = benchmark(CompilationMode.Partial(BaselineProfileMode.Require)) private fun benchmark(compilationMode: CompilationMode) { rule.measureRepeated( packageName = InstrumentationRegistry.getArguments().getString("targetAppId") ?: throw Exception("targetAppId not passed as instrumentation runner arg"), metrics = listOf(StartupTimingMetric()), compilationMode = compilationMode, StartupBenchmarks 44

Slide 45

Slide 45 text

プロファイル Profiles 劇的な改善にはボトルネック改善も必要 Dramatic improvement also requires bottleneck improvement 45

Slide 46

Slide 46 text

パフォーマンスモニタリング 
 Performance Monitoring 46

Slide 47

Slide 47 text

パフォーマンスモニタリング Performance Monitoring Firebase Performance Monitoring ・起動時間やネットワークリクエストなどを自動測定
  Automatic measurement of startup time and network requests  → FirebasePerfProvider.onCreate 〜 first Activity.onResume
 ・アラートによるパフォーマンス低下の検知
  Detection of performance degradation through alerts  → 指定したパーセンタイル値の閾値を超える
    Exceeds the specified percentile value threshold
 47

Slide 48

Slide 48 text

パフォーマンスモニタリング Performance Monitoring plugins { alias(libs.plugins.firebase.perf) apply false {project}/build.gradle dependencies { implementation(platform(libs.firebase.bom)) implementation(libs.firebase.perf) } app/build.gradle plugins { alias(libs.plugins.firebase.perf) … 48

Slide 49

Slide 49 text

パフォーマンスモニタリング Performance Monitoring 49

Slide 50

Slide 50 text

まとめ Summary 1 . アプリの起動時間とは What is application startup time? - Cold Start, Warm Start, Hot Start - TTID, TTFD 2 . パフォーマンス検査 Performance Inspection - Macrobenchmark, CPU Profiler 3 . パフォーマンス向上 Performance Improvements - App Startup, Baseline Profiles, Startup Profiles 4 . パフォーマンスモニタリング Performance Monitoring - Firebase Performance Monitoring 50

Slide 51

Slide 51 text

参照
 ● アプリの起動 
 ● アプリのスタートアップ
 
 ● App Startupについて
 
 ● Android 向け Performance Monitoring を使ってみる
 
 51

Slide 52

Slide 52 text

参照
 ● パフォーマンス監視ツールの活用 
 ● performance-samples
 
 ● いかにしてアプリの起動時間を改善するか
 
 ● Firebase Performance Monitoring
 
 52

Slide 53

Slide 53 text

ありがとうございました! Thank you so much for your kind attention.