Cold Start é o ciclo completo de inicialização de um aplicativo Android começando de um estado zero, quando o processo do aplicativo não existe na memória e a Activity não foi criada. O sistema cria um novo processo, carrega as classes, inicializa o Application, cria a Activity e executa o primeiro desenho. De acordo com Google, 2024, a inicialização a frio em dispositivos de gama média pode levar de 1 a 5 segundos, e cada 100 ms de atraso reduzem a probabilidade de retenção do usuário em 3%.
Pontos principais
Cold Start (inicialização a frio) é um cenário em que um aplicativo Android é iniciado a partir do estado mais inicial: o sistema operacional cria um novo processo (fork do Zygote), aloca memória, carrega o código DEX no ART, inicializa as classes e cria uma instância do Application, e então a primeira Activity. Antes da inicialização do app, não há dados sobre ele na memória do dispositivo, exceto imagens de classe em cache se Background Dexopt for usado.
A inicialização a frio ocorre em três casos: na primeira inicialização após a instalação do aplicativo, na inicialização após reinicialização do dispositivo e na inicialização após o sistema ter removido o processo por falta de memória. Em dispositivos com 2–4 GB de RAM, o sistema remove processos em segundo plano de forma bastante agressiva, portanto o Cold Start pode ocorrer toda vez que o usuário retorna ao aplicativo após várias horas de inatividade. No Android 12+, o sistema pode manter um processo congelado (freeze / cached), mas com economia ativa de memória (OOM-killer), o processo será encerrado.
De acordo com o Google (relatório Find My Device, 2023), 65% dos usuários fecham um aplicativo se ele não abrir em 3 segundos. Para redes sociais e mensageiros, onde os usuários retornam dezenas de vezes ao dia, o Cold Start afeta diretamente a retenção. No Google Play Console, a métrica Cold Start faz parte da seção Android Vitals e é exibida como um dos indicadores de ANR e desempenho. Um aplicativo que excede o limite de Cold Start “ruim” (mais de 5 segundos em 25% dos dispositivos) recebe um aviso no console e pode ser rebaixado nos resultados de pesquisa.
O Android distingue três tipos de inicialização de aplicativo, cada um com duração diferente, impacto na UX e abordagens de otimização. Entender a diferença é essencial para escolher a estratégia de perfilagem correta.
| Tipo de inicialização | Estado do processo | Application.onCreate | Tempo típico |
|---|---|---|---|
| Cold | Sem processo | Executado | 1–5 segundos |
| Warm | Processo existe, sem Activity | Não executado | 200–600 ms |
| Hot | Processo + Activity na memória | Não executado | < 200 ms |
Warm Start ocorre quando o processo do aplicativo já existe em segundo plano, mas a Activity foi destruída (por exemplo, o usuário voltou após uma longa pausa e o sistema liberou a memória da Activity). Hot Start — quando o usuário minimiza o aplicativo e o abre imediatamente: a Activity está pausada e a restauração leva tempo mínimo. Para o usuário, Cold Start é o tipo de inicialização mais perceptível, e sua otimização proporciona o maior ganho em UX.
Cold Start pode se tornar Warm Start depois que o aplicativo for iniciado pelo menos uma vez — o ART armazena em cache as imagens de classe compiladas (Image no Boot Profile) e o carregamento subsequente do DEX é mais rápido. Portanto, a segunda inicialização após o primeiro Cold Start geralmente é 20–40% mais rápida. Se o aplicativo usar Baseline Profiles, os perfis são carregados na primeira inicialização e a segunda inicialização pode ser ainda mais rápida: o Google Play, que publicou Baseline Profiles, acelerou o Cold Start em 30% em dispositivos com Android 12+.
Cold Start consiste em fases estritamente definidas, cada uma podendo ser medida e otimizada independentemente. Conhecer as fases ajuda a determinar em qual estágio o aplicativo está perdendo tempo. O Google identifica quatro fases principais: criação do processo, inicialização do Application, criação da Activity e primeiro quadro.
O sistema Android (ActivityManagerService) cria um novo processo por fork do processo Zygote. Zygote é um processo pré-carregado com classes comuns do Android. O fork leva 30–80 ms — esse tempo está fora do controle do aplicativo. Após o fork, o ActivityThread é iniciado — a instância do loop principal do aplicativo. Nesta fase, também ocorre o carregamento de classes via ClassLoader, e o ART começa a interpretar o primeiro bytecode. Se o aplicativo usa muitos inicializadores estáticos, esta fase pode se prolongar.
Imediatamente após o ActivityThread ser iniciado, Application.onCreate é chamado. Aqui é onde os desenvolvedores mais frequentemente cometem o erro de inicializar tudo de uma vez: Crashlytics, Firebase, clientes de rede, bancos de dados, componentes Dagger, contêineres DI. Cada uma dessas inicializações é tempo bloqueado na thread principal. Se o Application.onCreate leva 500 ms, o usuário vê uma tela branca (ou preta) por meio segundo. A duração ideal desta fase é inferior a 200 ms em um dispositivo de gama média.
Após a inicialização do Application, uma instância de Activity é criada (MainActivity ou Launcher Activity). Activity.onCreate é chamado, onde ocorrem setContentView, inicialização de fragmentos, configuração do ViewModel e assinatura de LiveData/Flow. Se o onCreate carrega dados (SharedPreferences, SQLite, API) de forma síncrona na thread principal, a fase se estende. O objetivo é manter o onCreate entre 200–400 ms em um dispositivo de gama média.
Após o término do onCreate, começa a primeira renderização: medida, layout, draw. Este momento é chamado de TTFD (Time To First Draw). Se o aplicativo usa uma tela de splash (via SplashScreen API no Android 12+ ou via theme), a renderização pode ocorrer mais rápido, mas o usuário ainda esperará até que o splash desapareça. O TTFD ideal para Cold Start é inferior a 1,5 segundos.
Medir Cold Start requer ferramentas especiais, pois o registro normal (Log.d) só começa a funcionar após a criação do Application, e o tempo do fork e carregamento de classes permanece inacessível. O Google recomenda três métodos: comandos ADB, Android Vitals e macros de desempenho personalizadas.
O método mais simples e reproduzível é o comando adb shell am start -S -W. A flag -S para forçosamente o aplicativo antes da inicialização (garante Cold Start). O comando gera três métricas: ThisTime (tempo de início da Activity), TotalTime (tempo total incluindo a inicialização do processo) e WaitTime (tempo incluindo todos os atrasos do Activity Manager). Para medições limpas, faça 5–7 leituras e use a mediana — leituras individuais estão sujeitas a ruído (CPU throttling, carga em segundo plano).
# Cold Start forçado com medição
$ adb shell am start -S -W \
com.example.app/.MainActivity
# Saída do comando:
# ThisTime: 1842 ms
# TotalTime: 1842 ms
# WaitTime: 1855 ms
O Google Play Console coleta métricas anônimas de todos os dispositivos onde o aplicativo está instalado. Na seção Android Vitals → Launch time, é exibida a distribuição mediana do Cold Start por modelo de dispositivo e versão do Android. Esta é a única maneira de ver métricas reais em dispositivos de usuários, não apenas em dispositivos de teste. Se o Cold Start exceder 5 segundos no Redmi 9A (2 GB RAM) e 1,2 segundos no Pixel 8, o problema é o tamanho da memória e a quantidade de classes. O Google também mostra o atraso perceptível pelo usuário com base no percentil 25.
O Google Jetpack Macrobenchmark (biblioteca androidx.benchmark) permite escrever testes instrumentados de inicialização de aplicativo. O teste instala o aplicativo, inicia-o a partir de um estado frio e mede o tempo até o primeiro quadro. Macrobenchmark executa automaticamente 20 iterações, descarta valores atípicos e mostra percentis estáveis. Para CI/CD, você pode comparar a linha de base e a inicialização atual — se o tempo aumentar, o pipeline de CI pode falhar.
Otimizar Cold Start é um trabalho sistemático que afeta vários níveis do aplicativo: código, recursos, configuração de compilação e arquitetura de inicialização. O Google recomenda começar pela parte mais cara — Application.onCreate — e avançar para os detalhes menores.
Mova toda a inicialização que não é necessária na inicialização para fora do Application.onCreate para o primeiro ponto de uso. Firebase, Crashlytics, SDK de análise, notificações push, componentes DI — tudo pode ser inicializado após a renderização da primeira tela. Use Lazy (by lazy) em Kotlin ou inicialização via ContentProvider com uma chamada explícita initialize(context). De acordo com o Google (Android Performance, 2023), a inicialização preguiçosa reduz Cold Start em 40–60% para aplicativos que usam 5+ SDKs.
Baseline Profiles são a compilação AOT de classes e métodos críticos usados na inicialização do aplicativo. Sem Baseline Profiles, o ART interpreta o código DEX ou o compila via JIT, o que leva tempo. Com os perfis, o ART compila os métodos especificados em código nativo (AOT) durante a instalação do aplicativo. O Google afirma que Baseline Profiles aceleram Cold Start em 15–40% no Android 9+ e até 60% com otimizações ART do Android 12+. Para criar perfis, use o plugin androidx.benchmark:benchmark-baseline-profile-gradle-plugin.
A biblioteca androidx.startup permite ordenar a inicialização de componentes e executá-la em um único ContentProvider. Em vez de vários ContentProviders de diferentes bibliotecas (cada um adiciona 1–2 ms à inicialização a frio), o App Startup os mescla em um grafo de dependências e inicializa estritamente conforme necessário. Na inicialização, apenas os componentes marcados com @Initializer que são necessários para a primeira tela são executados. Para os demais, a flag needEarlyInit = false é definida — eles são iniciados após a primeira renderização.
// App Startup Initializer — inicialização após o início
class AnalyticsInitializer : Initializer<Unit> {
override fun create(context: Context) {
Analytics.init(context)
}
override fun dependencies() = listOf<Class<out Initializer<*>>>()
}
// No AndroidManifest.xml marcar como opcional
// <meta-data android:name="AnalyticsInitializer"
// android:value="false" />
O tamanho do arquivo DEX afeta diretamente o tempo de carregamento do ART. Use R8/ProGuard para ofuscação e remoção de código morto (MinifyEnabled = true). Ative android:extractNativeLibs="false" no manifesto para que o APK não descompacte arquivos .so na instalação. Para projetos com mais de 10 rastreamentos de referência, adicione startup-priority apenas para a primeira tela. Cada método extra no DEX adiciona 0,5–2 ms ao carregamento, e para aplicativos com mais de 50k métodos (multidex com primary dex) — até 300 ms.
Android Vitals no Google Play Console (seção Launch time) coleta dados de todos os dispositivos onde o aplicativo está instalado, desde que o usuário tenha consentido com o diagnóstico anônimo. As métricas são divididas em três categorias: “bom”, “moderado”, “ruim”, dependendo do tempo de Cold Start.
O Google define Cold Start “ruim” como um tempo superior a 5 segundos em qualquer dispositivo. No entanto, na prática, para dispositivos emblemáticos (Snapdragon 8 Gen), um bom tempo é inferior a 1,5 segundos, para gama média — inferior a 2,5 segundos, para gama baixa — inferior a 4 segundos. O Android Vitals mostra a mediana para cada modelo de dispositivo, permitindo entender em quais dispositivos o aplicativo inicia lentamente. Se o Cold Start for ruim em dispositivos Samsung A-series ou Xiaomi Redmi, a causa geralmente é memória flash lenta e pouca RAM (a aceleração via Baseline Profiles produz o maior efeito precisamente nesses dispositivos).
Além de ser exibida no console, a métrica Cold Start afeta a classificação de qualidade do aplicativo no Google Play Search. Aplicativos com alta porcentagem de inicializações “ruins” recebem um rótulo de “Advertência de desempenho” na página de instalação, reduzindo a conversão. De acordo com o Google (Android Performance Playbook, 2024), aplicativos que resolveram problemas de Cold Start aumentaram a conversão de instalação em média 5% e melhoraram a retenção (D1) em 3–7%.
Para monitoramento mais detalhado, use Firebase Performance Monitoring. Ele rastreia Cold Start no nível de sessão, dividido por versão do aplicativo e versão do Android. Ao contrário do Android Vitals, o Firebase mostra um diagrama de trace do tempo gasto por fase. Por exemplo, você pode ver que na versão 3.2.0, o Application.onCreate levou 800 ms (devido a uma nova biblioteca de notificações push), enquanto na versão 3.2.1 — 200 ms (após a correção).
Abaixo estão dois exemplos práticos que aceleram diretamente o Cold Start: mover a inicialização de SDK após a inicialização e usar a SplashScreen API.
Um erro típico é inicializar todos os SDKs no Application.onCreate. Abaixo é mostrado como mover a inicialização não crítica para uma corrotina que é lançada após o desenho do primeiro quadro. Importante: Firebase, Crashlytics e SDKs de relatório de falhas devem ser inicializados na inicialização — eles não podem ser adiados porque capturam falhas durante a inicialização de outros componentes. Para o restante, use lifecycleScope na primeira Activity.
// ❌ Ruim — toda inicialização no Application.onCreate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this) // crítico
Analytics.init(this) // pode ser depois
Database.init(this) // pode ser depois
ImageLoader.init(this) // pode ser depois
}
}
// ✅ Bom — Firebase no início, o resto after inflate
class App : Application() {
override fun onCreate() {
super.onCreate()
Firebase.init(this)
}
}
// No MainActivity após o primeiro quadro:
lifecycleScope.launchWhenResumed {
initializeNonCriticalSdks()
}
No Android 12+, use a SplashScreen API oficial que mostra um splash do sistema (ícone do aplicativo em fundo escuro/claro) imediatamente quando o processo inicia. Isso oculta o tempo de inicialização do usuário — ele vê um splash em vez de uma tela branca. Para dispositivos mais antigos, use theme-based splash (Theme.SplashScreen em estilos). Importante: o splash não deve durar mais de 300 ms — se o aplicativo não estiver pronto até lá, desenhe um esqueleto “persistente” (shimmer) e mostre o progresso do carregamento.
// 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)
}
}
// Splash baseado em tema (Android 5-11)
// Em themes.xml:
// <style name="Theme.App.Starting" parent="Theme.SplashScreen">
// <item name="windowSplashScreenBackground">@color/white</item>
// <item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
// </style>
Perguntas frequentes
O emulador usa um computador host potente e emula o processador com aceleração de hardware (HAXM / WHPX). Dispositivos físicos, especialmente os de gama baixa (armazenamento eMMC em vez de UFS), têm E/S muito mais lenta. Recomenda-se medir Cold Start em um dispositivo físico de gama média para obter dados realistas.
De acordo com as recomendações do Google, a mediana do Cold Start deve ser inferior a 2 segundos em dispositivos de gama média. Para emblemáticos — inferior a 1,5 segundos. Para dispositivos de gama baixa (2 GB RAM), até 4 segundos é aceitável, mas recomenda-se otimizar para 3 segundos. Valores acima de 5 segundos são considerados críticos.
Indiretamente — sim. Se o manifesto contiver um ícone vetorial (AdaptiveIcon), ele deve ser compilado em um drawable na inicialização. Se o ícone contiver caminhos complexos (pathData com dezenas de curvas), a compilação leva 10–30 ms. Use VectorDrawable com pathData otimizado (via SVGOMG ou Android Studio Vector Asset).
Sim, se um Feature Module (Android App Bundle) for carregado sob demanda, seu Cold Start é medido desde o momento em que o recurso é tocado até o primeiro quadro. Módulos sob demanda são carregados via Play Core Library e sua instalação adiciona 500–3000 ms ao tempo de inicialização. Otimize o código do recurso da mesma forma que o módulo principal.
Aplicativos com mais de 64k métodos exigem Multidex. Isso significa que o ART deve carregar vários arquivos DEX, aumentando o tempo de Cold Start em 200–800 ms, dependendo do número de arquivos classes.dex. Use minSdk 21+ (ART com suporte nativo a multidex) e configure primary dex via --main-dex-list para manter as classes críticas no primeiro arquivo DEX.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também