Hot Startとは、プロセスがすでにメモリに存在している状態で、最小化されたモバイルアプリを起動することです。システムがゼロからプロセスを作成するCold Startとは異なり、ホットスタートは200~500ミリ秒かかり、ActivityのonCreateとonStartの呼び出しに限定されます。Android Developers(2025年)によると、Hot Startは最も高速なシナリオですが、その速度はライフサイクルメソッドでの作業量に直接依存します。
重要ポイント
Hot Startは、アプリのプロセスがデバイスのRAMにすでに存在している起動シナリオです。ユーザーがアプリを最小化し、その後戻ると、システムは新しいプロセスを作成せずに既存のプロセスを再開します。このシナリオでは、OSのロード、Applicationクラスの初期化、プロセスの作成が不要なため、UIが画面に表示されるまでの時間が劇的に短縮されます。Androidのドキュメント(2025年)によると、Hot Startはわずか200~500ミリ秒しかかからないのに対し、Cold Startは5秒以上かかる場合があります。速度の差は、メモリが限られたデバイスで特に顕著であり、システムはバックグラウンドアプリをより頻繁にアンロードします。
Hot Startの主な特徴は、呼び出されるライフサイクルメソッドの最小セットです。AndroidではActivity.onCreateとActivity.onStart、iOSではapplicationDidBecomeActiveです。Application.onCreate、ContentProvider.onCreate、Activity.onCreate、および多くのライブラリ初期化が順次呼び出されるCold Startとは異なり、Hot Startはこれらの段階をすべてスキップします。開発者は、ホットスタート中に特にどのコードが実行されるかを理解する必要があります。多くの場合、SDKの初期化、分析、DIコンテナは、ホットスタート中には不要であるにもかかわらず、Cold StartとHot Startの両方で繰り返されます。
3つのアプリ起動シナリオは、初期化の深さが異なります。Cold Startは、インストール後、デバイスの再起動後、またはメモリから削除された後にアプリが初めて起動されるときに発生します。システムは新しいLinuxプロセスを作成し、Applicationクラスをロードし、ContentProviderインスタンスを作成し、ライブラリの初期化を実行し、その後でActivityをレンダリングします。プロセス全体は、アプリの複雑さとデバイスの特性に応じて2~10秒かかります。
Warm Startは中間的なシナリオです。アプリのプロセスはメモリ上で生きていますが、Activityは破棄されており、再作成する必要があります。これは、例えば画面の回転や、メモリ不足のためにActivityが削除されたがプロセスは残っている別のアプリから戻る場合に発生します。Warm StartにはActivity.onCreateとActivity.onStartの呼び出しが含まれますが、Application.onCreateやContentProviderの初期化は含まれません。Warm Startの時間は500ミリ秒から2秒です。Hot Startは3つの中で最速です。Activityはすでにバックスタックに存在し、プロセスは生きており、システムは単にActivity.onRestart、onStart、onResumeを呼び出します。Hot Startの時間は200~500ミリ秒です。Warm Startとの違いは、Activityが新たに作成されるのではなく、既存のインスタンスから復元されることです。
| パラメータ | Cold Start | Warm Start | Hot Start |
|---|---|---|---|
| プロセス | 新たに作成 | 存在 | 存在 |
| Activity | 新たに作成 | 新たに作成 | 復元 |
| Application.onCreate | 呼び出される | 呼び出されない | 呼び出されない |
| 典型的な時間 | 2~10秒 | 0.5~2秒 | 0.2~0.5秒 |
| ライフサイクルメソッド | すべて | onCreate + onStart | onRestart + onStart |
Androidでは、Hot Startは、ユーザーがRecent画面から、または最小化中にアプリアイコンをタップしてアプリに戻ったときにトリガーされます。システムはプロセスが生きているかどうかを確認し、生きている場合は、Activity.onRestart、onStart、onResumeを順に呼び出します。Hot Start中はonCreateメソッドは呼び出されません。Activityインスタンスがすでにメモリ上に存在するためです。これは、Activityの破棄によりonCreateがまだ呼び出されるWarm Startとの重要な違いです。Google I/O 2019によると、Androidの典型的なHot Start時間は200~400ミリ秒であり、この段階での速度低下は、知覚される起動時間を直接増加させます。
開発者は、UI初期化コード、LiveDataサブスクリプション、RecyclerViewのセットアップがonCreateだけでなく、onStartやonResumeでも実行されることを見落としがちです。Hot Start中、UIはすでに設定されているにもかかわらず、これらのコードブロックが再び実行されます。1回限りの初期化(savedInstanceStateのチェックを伴うonCreate内)と再開可能なロジック(onStart/onResume)を分離することをお勧めします。たとえば、アダプターのセットアップやリストのロードなどの重い操作は、onRestart中に実行されないブロックに移動するか、savedInstanceStateをチェックする必要があります。
次のKotlinコードは、起動シナリオを検出し時間を測定する簡単な方法を示しています。launchTimeStamp変数は起動開始の瞬間をキャプチャし、isColdStartはコールドスタートとホットスタートのロジックを分離できます。
class MainActivity : AppCompatActivity() {
private var launchTimeStamp = 0L
private var isColdStart = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
isColdStart = true
launchTimeStamp = System.currentTimeMillis()
// 1回限りの初期化
} else {
isColdStart = false
// Hot Start — Activityが復元される
}
}
override fun onResume() {
super.onResume()
if (isColdStart) {
val launchTime =
System.currentTimeMillis() - launchTimeStamp
Log.d("LaunchTime", "Cold Start: $launchTime ms")
}
}
}
iOSでは、Hot Startは、sceneDidBecomeActive(UIKit)またはonAppear(SwiftUI)を介してバックグラウンドからアプリに戻ることに対応します。アプリがSuspendedまたはBackground状態の場合、オペレーティングシステムはプロセスを再作成しません。ホット起動中は、AppDelegateでapplicationDidBecomeActiveが呼び出されますが、applicationDidFinishLaunchingは呼び出されません。これは、Application.onCreateがスキップされるAndroidと同様です。iOSはより積極的にアプリをメモリから解放します。デバイスにRAMが不足している場合、システムはバックグラウンドアプリを解放し、次の起動はCold Startになります。Apple Developerのドキュメントによると、iOSの平均Hot Start時間は300~600ミリ秒です。
iOSの重要な違いは、Androidの意味でのWarm Startの直接的な類似物がないことです。iOSでは、アプリが最小化されるとsceneDidEnterBackgroundが呼び出され、戻るときにsceneWillEnterForegroundとsceneDidBecomeActiveが呼び出されます。システムがシーンを解放してもプロセスを生かしたままにする場合、次の起動はシーンの観点からはColdですが、プロセスの観点からはHotになります。開発者は初期化コードを配置する際にこれを考慮する必要があります。NotificationCenterへのサブスクリプション、UIの更新、状態のリセットは、viewDidLoadだけでなくsceneDidBecomeActiveに配置する必要があります。
このSwiftコードは、ホット起動の数を追跡し、ロジックを分離する方法を示しています。foregroundCountカウンターは、バックグラウンドから戻るたびに増加します。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var foregroundCount = 0
func sceneDidBecomeActive(
_ scene: UIScene
) {
foregroundCount += 1
if foregroundCount == 1 {
// Cold Start — 完全な初期化
setupSDKs()
} else {
// Hot Start — UI更新のみ
refreshUI()
}
}
private func refreshUI() {
// 画面上のデータ更新
}
}
Hot Startの速度には、いくつかのカテゴリの要因が影響します。1つ目は、onStartおよびonResumeライフサイクルメソッドでの作業量です。開発者がこれらのメソッドにネットワークデータのロード、JSON解析、アダプターの初期化、または重い計算を配置した場合、そのようなブロックごとに起動時間に数十から数百ミリ秒が追加されます。Android Vitalsによると、Hot Start時間が800ミリ秒を超えるアプリは、戻ってきたときに最大20%のユーザーを失います。
2つ目のカテゴリは、savedInstanceStateから復元されるフラグメントとビューです。フラグメントに重いViewPager2、WebView、または複雑で深くネストされた階層が含まれている場合、それらの復元はCPUリソースを消費します。Google I/O 2023によると、ネストされたViewGroupごとに、Hot Start中のレンダリング時間に平均2~5ミリ秒が追加されます。3つ目のカテゴリは、サードパーティのSDKです。分析ライブラリ、クラッシュレポートツール、A/Bテストフレームワーク、DEXローダーは、バックグラウンドから戻るたびに初期化を実行する場合があります。どのSDKが特にonStart/onResumeでコードを実行するかを確認し、重要でないタスクをバックグラウンドスレッドに延期することをお勧めします。
Hot Startの最適化は、再開ライフサイクルメソッドでの作業を最小限に抑えることに帰着します。1つ目の方法は遅延初期化です。最初のUIフレームに不要なコードは、onResumeの後、Handler.postDelayedまたはCoroutine.launch(Dispatchers.IO)を介して遅延実行する必要があります。2つ目の方法はビュー状態のキャッシュです。アプリが最小化されたら、データをインメモリキャッシュに保存して、Hot Start中にデータベースやネットワークから再ロードする必要がないようにします。3つ目の方法は、AndroidでSavedStateHandle、iOSでStateRestorationPolicyを使用して、復元されるデータ量を最小限に抑えることです。
この例では、Handler.postDelayedが、最初のフレームのレンダリング後500ミリ秒後に分析の初期化を延期します。ユーザーはすでにインターフェースを認識しているため、これは知覚される起動時間に影響しません。
class AnalyticsDeferrer {
fun lazyInitAfterHotStart() {
val handler = Handler(Looper.getMainLooper())
handler.postDelayed({
// 最初のフレーム後の初期化
Analytics.init(Application.getInstance())
CrashReporter.start()
}, 500)
}
}
AndroidX App Startupを使用すると、起動時のコンポーネントの初期化順序を制御できます。すべてのContentProviderはCold Start中に自動的に初期化されますが、Hot Start中に不要なコンポーネントの自動初期化を無効にできます。
@Initializer(Application::class)
class SdkInitializer : Initializer<Unit> {
override fun create(context: Context) {
SdkOne.init(context)
SdkTwo.init(context)
}
override fun dependencies() = emptyList<Class<*>>()
}
Hot Start時間を測定するには、プラットフォームの組み込みツールとサードパーティのソリューションの両方があります。Androidでは、主要なツールはGoogle Play ConsoleのAndroid Vitalsです。これは、デバイスモデルとOSバージョンごとに分類されたすべてのシナリオ(Cold、Warm、Hot)の起動時間メトリクスを自動的に収集します。さらに、AndroidXのMacrobenchmark(自動起動パフォーマンステスト用のライブラリ)を使用することもできます。iOSでは、これに相当するのはMetricKitで、起動時間、フレームレート、メモリ使用量に関するデータを収集します。
詳細なホットスタートプロファイリングには、Firebase Performance Monitoring(カスタムトレースを追跡)および起動時間ダッシュボード付きのNew Relicが適しています。開発者側での手動測定には、AndroidのreportFullyDrawnが使用されます。これは、UIがレンダリングされ、操作の準備ができた正確な瞬間をシステムに通知するAPIです。iOSでは、MetricKitのendActivityがこれに相当します。これらのツールを組み合わせることで、特定のデバイスでどのSDKまたはコードブロックがHot Startを遅くしているかを特定できます。
Macrobenchmarkライブラリを使用したKotlinコードで、Cold StartとHot Startを測定します。テストはActivityを起動し、完了状態までの時間を測定します。
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun hotStart() {
benchmarkRule.measureRepeated(
packageName = "com.example.app",
metrics = listOf(StartupTimingMetric()),
iterations = 10,
startupMode = StartupMode.HOT
) {
pressHome()
startActivityAndWait()
}
}
}
よくある質問
Cold Startはゼロからプロセスを作成します(Application、ContentProviderをロードし、すべてのライフサイクルメソッドを実行)。Hot Startは既存のプロセスを使用し、Activityの再作成を必要としないため、5~10倍高速です。
AndroidのHot Start中は、Activity.onRestart、次にonStart、onResumeが呼び出されます。Activityインスタンスはすでにメモリ上に存在し、破棄されていないため、onCreateメソッドは呼び出されません。
主な理由は、onStartとonResumeでの重い初期化、ネットワークデータのロード、複雑なビュー階層の復元、およびバックグラウンドから戻るたびに実行されるサードパーティSDKコードです。
AndroidではStartupMode.HOTを指定したMacrobenchmark、iOSではMetricKitを使用します。本番監視には、Firebase PerformanceとGoogle Play ConsoleのAndroid Vitalsが適しています。
いいえ。Hot StartとWarm Startはシステムによって決定される異なるシナリオです。Hot StartはActivityが生きている場合に発生し、Warm StartはActivityが破棄されているがプロセスが生きている場合に発生します。開発者がシナリオを強制的に変更することはできません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。