Cold Start — コールドスタートとAndroidでの最適化

著者: IT Sectr 公開日: 2026-03-31 読了時間: 9 分

Cold Startとは、アプリケーションのプロセスがメモリに存在せず、Activityが作成されていないゼロ状態から始まるAndroidアプリケーションの完全な起動サイクルです。システムは新しいプロセスを作成し、クラスをロードし、Applicationを初期化し、Activityを作成し、最初の描画を実行します。Google、2024年によると、ミッドレンジデバイスでのコールドスタートには1〜5秒かかる可能性があり、100ミリ秒の遅延ごとにユーザー維持確率が3%低下します。

重要なポイント

  • Cold Start — Androidアプリをゼロから起動:新しいプロセス、クラスロード、初期化
  • メトリクスはプロセス開始から最初の描画(TTIDまたはTTFD)まで測定
  • 起動の段階:プロセス作成 → Application.onCreate → Activity.onCreate → 最初のフレーム
  • 最適化には遅延初期化、Baseline Profiles、DEXサイズ削減が含まれる
  • Google PlayはAndroid VitalsでCold Startを主要メトリクスの一つとして使用

Cold Startとは

Cold Start(コールドスタート)は、Androidアプリケーションが最も初期の状態から起動されるシナリオです:オペレーティングシステムが新しいプロセスを作成し(Zygoteからのfork)、メモリを割り当て、DEXコードをARTにロードし、クラスを初期化し、Applicationインスタンスを作成し、次に最初のActivityを作成します。アプリ起動前には、Background Dexoptが使用されている場合のキャッシュされたクラスイメージを除き、デバイスメモリにアプリに関するデータはありません。

Cold Startが発生するタイミング

コールドスタートは3つのケースで発生します:アプリインストール後の初回起動時、デバイス再起動後の起動時、そしてメモリ不足によりシステムがプロセスを削除した後の起動時です。2〜4GBのRAMを搭載したデバイスでは、システムはバックグラウンドプロセスをかなり積極的に削除するため、Cold Startはユーザーが数時間の非アクティブ後にアプリに戻るたびに発生する可能性があります。Android 12+では、システムは凍結されたプロセス(freeze / cached)を保持できますが、アクティブなメモリ節約(OOM-killer)により、プロセスは終了されます。

Cold Startが重要なメトリクスである理由

Google(Find My Deviceレポート、2023年)によると、65%のユーザーがアプリが3秒以内に開かない場合に閉じます。ソーシャルネットワークやメッセンジャーでは、ユーザーが1日に何十回も戻ってくるため、Cold Startはリテンションに直接影響します。Google Play Consoleでは、Cold StartメトリクスはAndroid Vitalsセクションの一部であり、ANRとパフォーマンス指標の一つとして表示されます。「不良」のCold Startしきい値(25%のデバイスで5秒以上)を超えるアプリは、コンソールで警告を受け、検索結果で順位が下がる可能性があります。

Cold Start vs Warm Start vs Hot Start

Androidは3種類のアプリ起動を区別しており、それぞれ持続時間、UXへの影響、最適化アプローチが異なります。違いを理解することは、適切なプロファイリング戦略を選択するために不可欠です。

起動タイププロセス状態Application.onCreate標準的な時間
Coldプロセスなし実行される1〜5秒
Warmプロセスあり、Activityなし実行されない200〜600ミリ秒
Hotプロセス+Activityがメモリ内実行されない< 200ミリ秒

Warm Startは、アプリプロセスが既にバックグラウンドに存在するが、Activityが破棄された場合に発生します(例えば、ユーザーが長い休止の後に戻り、システムがActivityのメモリを解放した場合)。Hot Startは、ユーザーがアプリを最小化してすぐに再度開いた場合に発生します:Activityは一時停止されており、復元に最小限の時間しかかかりません。ユーザーにとって、Cold Startは最も顕著な起動タイプであり、その最適化はUXに最大の改善をもたらします。

タイプ間の移行

アプリが少なくとも一度起動された後、Cold StartはWarm Startになる可能性があります — ARTはコンパイルされたクラスイメージ(Boot ProfileのImage)をキャッシュし、その後のDEXロードが高速になります。したがって、最初のCold Start後の2回目の起動は通常20〜40%高速です。アプリがBaseline Profilesを使用する場合、プロファイルは最初の起動時にロードされ、2回目の起動はさらに高速になります:Baseline Profilesを公開したGoogle Playは、Android 12+搭載デバイスでCold Startを30%高速化しました。

コールドスタートの段階

Cold Startは厳密に定義された段階で構成され、それぞれ独立して測定および最適化できます。段階を理解することで、アプリがどの段階で時間を失っているかを特定できます。Googleは4つの主要な段階を特定しています:プロセス作成、Application初期化、Activity作成、最初のフレーム。

段階1:プロセス作成(fork)

Androidシステム(ActivityManagerService)は、Zygoteプロセスからのforkによって新しいプロセスを作成します。Zygoteは一般的なAndroidクラスが事前にロードされたプロセスです。forkには30〜80ミリ秒かかります — この時間はアプリの制御外です。fork後、ActivityThreadが開始されます — アプリケーションのメインループインスタンスです。この段階では、ClassLoaderを介したクラスロードも発生し、ARTが最初のバイトコードの解釈を開始します。アプリが多くの静的初期化子を使用する場合、この段階は長引く可能性があります。

段階2:Application.onCreate

ActivityThreadの開始直後に、Application.onCreateが呼び出されます。ここで開発者は最も頻繁に誤りを犯し、すべてを一度に初期化します:Crashlytics、Firebase、ネットワーククライアント、データベース、Daggerコンポーネント、DIコンテナ。これらの各初期化はメインスレッドでブロックされる時間です。Application.onCreateに500ミリ秒かかる場合、ユーザーは0.5秒間、白(または黒)の画面を見ることになります。ミッドレンジデバイスでのこの段階の最適な持続時間は200ミリ秒未満です。

段階3:Activity.onCreate

Applicationの初期化後、Activityインスタンスが作成されます(MainActivityまたはLauncher Activity)。Activity.onCreateが呼び出され、setContentView、フラグメントの初期化、ViewModelのセットアップ、LiveData/Flowのサブスクリプションが行われます。onCreateがメインスレッドでデータ(SharedPreferences、SQLite、API)を同期的にロードする場合、段階が延長されます。目標は、ミッドレンジデバイスでonCreateを200〜400ミリ秒に収めることです。

段階4:最初のフレーム(TTFD)

onCreateの完了後、最初のレンダリングが開始されます:測定、レイアウト、描画。この瞬間をTTFD(Time To First Draw)と呼びます。アプリがスプラッシュ画面(Android 12+のSplashScreen API、またはテーマ経由)を使用する場合、レンダリングはより速く行われる可能性がありますが、ユーザーはスプラッシュが消えるまで待機します。Cold Startの理想的なTTFDは1.5秒未満です。

Cold Startの測定方法

Cold Startの測定には特別なツールが必要です。通常のロギング(Log.d)はApplication作成後にしか機能し始めず、forkのタイミングとクラスロードにはアクセスできないためです。Googleは3つの方法を推奨しています:ADBコマンド、Android Vitals、カスタムパフォーマンスマクロ。

ADBによる測定

最もシンプルで再現性のある方法は、adb shell am start -S -Wコマンドです。-Sフラグは起動前にアプリを強制的に停止します(Cold Startを保証)。コマンドは3つのメトリクスを出力します:ThisTime(Activity開始時間)、TotalTime(プロセス起動を含む合計時間)、WaitTime(Activity Managerのすべての遅延を含む時間)。クリーンな測定のために、5〜7回の測定を行い、中央値を使用してください — 単一の測定値はノイズ(CPUスロットリング、バックグラウンド負荷)の影響を受けます。

bash
# 測定を伴う強制Cold Start
$ adb shell am start -S -W \
    com.example.app/.MainActivity

# コマンド出力:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms

Android Vitals(Google Play Console)

Google Play Consoleは、アプリがインストールされているすべてのデバイスから匿名メトリクスを収集します。Android Vitals → Launch timeセクションには、デバイスモデルとAndroidバージョン別のCold Startの中央値分布が表示されます。これは、テストデバイスだけでなく、ユーザーのデバイスでの実際のメトリクスを確認する唯一の方法です。Redmi 9A(2GB RAM)でCold Startが5秒を超え、Pixel 8で1.2秒の場合、問題はメモリサイズとクラス数です。Googleは25パーセンタイルに基づくユーザー知覚遅延も表示します。

Macrobenchmark

Google Jetpack Macrobenchmark(androidx.benchmarkライブラリ)を使用すると、インストルメント化されたアプリ起動テストを作成できます。テストはアプリをインストールし、コールド状態から起動し、最初のフレームまでの時間を測定します。Macrobenchmarkは自動的に20回の実行を行い、外れ値を破棄し、安定したパーセンタイルを表示します。CI/CDでは、ベースラインと現在の起動を比較できます — 時間が増加した場合、CIパイプラインを失敗させることができます。

Cold Startの最適化方法

Cold Startの最適化は、コード、リソース、ビルド構成、初期化アーキテクチャなど、アプリの複数のレベルに影響を与える体系的な作業です。Googleは最もコストのかかる部分 — Application.onCreate — から始めて、細部に進むことを推奨しています。

遅延初期化(Lazy Init)

起動時に必要ないすべての初期化をApplication.onCreateから最初の使用ポイントに移動します。Firebase、Crashlytics、アナリティクスSDK、プッシュ通知、DIコンポーネント — すべて最初の画面がレンダリングされた後に初期化できます。KotlinではLazy(by lazy)を、または明示的なinitialize(context)呼び出しによるContentProvider初期化を使用します。Google(Android Performance、2023年)によると、遅延初期化は5つ以上のSDKを使用するアプリのCold Startを40〜60%削減します。

Baseline Profiles

Baseline Profilesは、アプリ起動時に使用される重要なクラスとメソッドのAOTコンパイルです。Baseline Profilesがない場合、ARTはDEXコードを解釈するかJITでコンパイルするため、時間がかかります。プロファイルを使用すると、ARTはアプリインストール時に指定されたメソッドをネイティブコード(AOT)にコンパイルします。Googleは、Baseline ProfilesがAndroid 9+でCold Startを15〜40%、Android 12+のART最適化で最大60%高速化すると述べています。プロファイルを作成するには、androidx.benchmark:benchmark-baseline-profile-gradle-pluginプラグインを使用します。

App Startup Library

androidx.startupライブラリを使用すると、コンポーネントの初期化を整理し、単一のContentProviderで実行できます。異なるライブラリの複数のContentProvider(それぞれがコールドスタートに1〜2ミリ秒追加)の代わりに、App Startupはそれらを依存関係グラフにマージし、必要に応じて厳密に初期化します。起動時には、最初の画面に必要な@Initializerでマークされたコンポーネントのみが実行されます。その他にはneedEarlyInit = falseフラグが設定され、最初のレンダリング後に起動されます。

kotlin
// App Startup Initializer — 起動後の初期化
class AnalyticsInitializer : Initializer<Unit> {
    override fun create(context: Context) {
        Analytics.init(context)
    }
    override fun dependencies() = listOf<Class<out Initializer<*>>>()
}

// AndroidManifest.xmlでオプションとしてマーク
// <meta-data android:name="AnalyticsInitializer"
//     android:value="false" />

DEXサイズの削減

DEXファイルのサイズは、ARTのロード時間に直接影響します。難読化とデッドコード削除にはR8/ProGuardを使用します(MinifyEnabled = true)。マニフェストでandroid:extractNativeLibs="false"を有効にすると、APKがインストール時に.soファイルを展開しなくなります。10以上の参照追跡を持つプロジェクトでは、最初の画面にのみstartup-priorityを追加します。DEXのメソッドが1つ増えるごとにロード時間が0.5〜2ミリ秒増加し、50k以上のメソッドを持つアプリ(primary dexを持つmultidex)では最大300ミリ秒になります。

Android VitalsにおけるCold Start

Google Play ConsoleのAndroid Vitals(Launch timeセクション)は、ユーザーが匿名診断に同意した場合に、アプリがインストールされているすべてのデバイスからデータを収集します。メトリクスはCold Start時間に基づいて3つのカテゴリに分けられます:「良好」、「普通」、「不良」。

Googleのしきい値

Googleは「不良」のCold Startを、任意のデバイスで5秒を超える時間と定義しています。ただし、実際には、フラッグシップデバイス(Snapdragon 8 Gen)では良好な時間は1.5秒未満、ミッドレンジでは2.5秒未満、低価格帯では4秒未満です。Android Vitalsは各デバイスモデルの中央値を表示し、どのデバイスでアプリの起動が遅いかを把握できます。Samsung A-seriesやXiaomi RedmiデバイスでCold Startが不良の場合、原因はほとんどの場合、フラッシュメモリの低速さとRAMの少なさです(Baseline Profilesによる高速化は、このようなデバイスで最も効果を発揮します)。

Google Playがメトリクスをどのように使用するか

コンソールでの表示に加えて、Cold StartメトリクスはGoogle Play Searchでのアプリ品質評価に影響します。「不良」起動の割合が高いアプリは、インストールページに「パフォーマンス警告」ラベルが表示され、コンバージョンが低下します。Google(Android Performance Playbook、2024年)によると、Cold Startの問題を解決したアプリは、インストールコンバージョンが平均5%向上し、リテンション(D1)が3〜7%改善されました。

Firebase Performanceとの統合

より詳細な監視には、Firebase Performance Monitoringを使用します。これはセッションレベルでCold Startを追跡し、アプリバージョンとAndroidバージョンごとに分類します。Android Vitalsとは異なり、Firebaseはフェーズごとの消費時間のトレース図を表示します。例えば、バージョン3.2.0ではApplication.onCreateに800ミリ秒かかった(新しいプッシュ通知ライブラリのため)が、バージョン3.2.1では200ミリ秒(修正後)であることがわかります。

最適化のためのコード例

以下に、Cold Startを直接高速化する2つの実践的な例を示します:起動後のSDK初期化の移動とSplashScreen APIの使用。

Application.onCreateからの初期化の移動

典型的な誤りは、すべてのSDKをApplication.onCreateで初期化することです。以下では、重要でない初期化を最初のフレーム描画後に起動するコルーチンに移動する方法を示します。重要:Firebase、Crashlytics、Crash Reporting SDKは起動時に初期化する必要があります — これらは他のコンポーネントの初期化中にクラッシュをキャッチするため、延期できません。残りについては、最初のActivityでlifecycleScopeを使用します。

kotlin
// ❌ 悪い — すべての初期化をApplication.onCreateで
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Firebase.init(this) // クリティカル
        Analytics.init(this) // 後で可能
        Database.init(this) // 後で可能
        ImageLoader.init(this) // 後で可能
    }
}

// ✅ 良い — Firebaseは起動時、残りはafter inflate
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Firebase.init(this)
    }
}

// 最初のフレーム後のMainActivityで:
lifecycleScope.launchWhenResumed {
    initializeNonCriticalSdks()
}

SplashScreen API

Android 12+では、プロセス開始時にシステムスプラッシュ(暗い/明るい背景にアプリアイコン)を即座に表示する公式のSplashScreen APIを使用します。これにより、ユーザーから初期化時間が隠蔽されます — 白い画面の代わりにスプラッシュが表示されます。古いデバイスでは、theme-based splash(スタイルのTheme.SplashScreen)を使用します。重要:スプラッシュは300ミリ秒以上続くべきではありません — それまでにアプリの準備ができていない場合は、「永続的な」スケルトン(shimmer)を描画し、読み込み進捗を表示します。

kotlin
// SplashScreen API — Android 12+
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()
        splashScreen.setKeepOnScreenCondition {
            isReady.value == false
        }
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

// テーマベースのスプラッシュ(Android 5-11)
// themes.xml内:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
//   <item name="windowSplashScreenBackground">@color/white</item>
//   <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>

よくある質問

エミュレーターのCold Startが実機より速いのはなぜですか?

エミュレーターは強力なホストコンピューターを使用し、ハードウェアアクセラレーション(HAXM / WHPX)でプロセッサをエミュレートします。物理デバイス、特に低価格帯のもの(UFSではなくeMMCストレージ)は、I/Oがはるかに遅くなります。現実的なデータを得るには、ミッドレンジの物理デバイスでCold Startを測定することをお勧めします。

どの程度のCold Startが許容されますか?

Googleの推奨によると、ミッドレンジデバイスでの中央値Cold Startは2秒未満であるべきです。フラッグシップでは1.5秒未満。低価格帯デバイス(2GB RAM)では最大4秒まで許容されますが、3秒への最適化が推奨されます。5秒を超える値は重大と見なされます。

アイコンのサイズはCold Startの速度に影響しますか?

間接的には — はい。マニフェストにベクターアイコン(AdaptiveIcon)が含まれている場合、起動時にdrawableにコンパイルする必要があります。アイコンに複雑なパス(数十の曲線を持つpathData)が含まれている場合、コンパイルに10〜30ミリ秒かかります。最適化されたpathData(SVGOMGまたはAndroid Studio Vector Asset経由)を持つVectorDrawableを使用してください。

Feature ModuleでCold Startを最適化する必要がありますか?

はい、Feature Module(Android App Bundle)がオンデマンドでロードされる場合、そのCold Startは機能をタップしてから最初のフレームまで測定されます。オンデマンドモジュールはPlay Core Libraryを介してロードされ、そのインストールにより起動時間に500〜3000ミリ秒追加されます。メインモジュールと同じように機能コードを最適化してください。

MultidexはCold Startにどのように影響しますか?

64kを超えるメソッドを持つアプリにはMultidexが必要です。これはARTが複数のDEXファイルをロードする必要があることを意味し、classes.dexファイルの数に応じてCold Start時間が200〜800ミリ秒増加します。minSdk 21+(ネイティブmultidexサポート付きART)を使用し、重要なクラスを最初のDEXファイルに保持するために--main-dex-listを介してprimary dexを設定してください。

まとめ

  • Cold Start — 新しいプロセス作成を伴う完全なアプリ起動、時間1〜5秒
  • ADB shell am start -S -WまたはCI/CDのMacrobenchmarkで測定
  • 4つの段階:fork → Application.onCreate → Activity.onCreate → 最初のフレーム
  • 最適化:遅延初期化、Baseline Profiles、App Startup Library、R8圧縮
  • Google Playは任意のデバイスで5秒を超えるとCold Startを「不良」と評価
  • Android 12+のSplashScreen APIがシステムスプラッシュで初期化時間を隠蔽
  • 100ミリ秒の遅延ごとにユーザーリテンションが3%低下

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください