Android'de Baseline Profiles: 2026'da soğuk başlatma süresini asıl ne değiştiriyor
Android Baseline Profiles için pratik bir rehber — Macrobenchmark ile profil oluşturma, Gradle'a bağlama, gerçek kazancı ölçme ve soğuk başlatmayı asıl etkileyen üç şey daha.
Soğuk başlatma, her kullanıcının hissettiği ama neredeyse kimsenin ölçmediği performans rakamıdır. Simgeye dokunursunuz, kısa bir boş ekran ya da esnemiş bir açılış ekranı anı yaşanır, sonra uygulama görünür. 500ms altındaysa kimse fark etmez. Bir saniyeyi geçince, ondan sonraki her ekran anında açılsa bile “yavaş” olarak algılanır — ilk izlenimler yapışkandır ve uygulama simgesi ilk izlenimdir.
Bu rakamın büyük kısmı layout’unuz ya da veritabanı sorgunuz değildir. JIT derleyicisinin, elinde optimize edebileceği bir profil olmadan uygulamanızın en sık çalışan kod yollarında soğuk, yorumlanmış (interpreted) iş yapmasıdır. Baseline Profiles tam olarak bu ısınma süresini atlamak için var ve Android’in az sayıdaki, bir öğleden sonrası harcayıp her yeni kurulumda ödeme yapmaya devam eden performans araçlarından biri.
Baseline Profile aslında nedir
Baseline Profile — baseline-prof.txt — uygulamanızın en yaygın akışlarında, soğuk başlatma ve profillemeyi seçtiğiniz diğer yolculuklarda dokunduğu sınıfları ve metodları listeleyen bir metin dosyasıdır. Bunu APK/AAB içinde gönderirsiniz ve Android Runtime (ART), bu metodları ilk kullanımda yorumlamak ya da JIT ile derlemek yerine önceden (ahead-of-time) derlemek için kullanır.
Etki dar ama gerçektir: kodunuzu hızlandırmaz, yalnızca çalışma sırasında gerçekten çalışan spesifik kod üzerindeki yorumlama vergisini kaldırır. Google, Play’de bunu daha önce hiç profili olmayan uygulamalarda soğuk başlatma süresini genellikle %20-30 aralığında kısalttığını raporluyor — sizin kazancınız tamamen başlatma yolunuzun ne kadarının gerçekten kapsandığına bağlı.
Macrobenchmark ile profil oluşturma
Profilin gerçek, enstrümante edilmiş bir çalıştırmadan gelmesi gerekir — anlamlı şekilde elle yazamazsınız. androidx.benchmark.macro kütüphanesi bunu yapar:
// build.gradle.kts (baselineprofile modülü)
plugins {
id("androidx.baselineprofile")
}
dependencies {
baselineProfile(project(":app"))
}
@RunWith(AndroidJUnit4::class)
class BaselineProfileGenerator {
@get:Rule
val rule = BaselineProfileRule()
@Test
fun generate() = rule.collect(
packageName = "com.mfk.hydrame",
includeInStartupProfile = true,
) {
pressHome()
startActivityAndWait()
// Önceden derlemeye değer akışları çalıştırın — sadece splash değil.
device.findObject(By.text("Log a glass")).click()
device.waitForIdle()
}
}
:app:generateBaselineProfile Gradle görevini gerçek bir cihazda ya da makul hızda bir emülatörde çalıştırın (profil oluşturma, root benzeri enstrümantasyon derlemesi gerektirir, eklenti bunu halleder). Bu, o senaryolu çalıştırma sırasında dokunulan her sınıfı kaydeder ve baseline-prof.txt dosyasını app/src/main/ altına yazar; AGP baseline profile eklentisi bunu release derlemeleri için otomatik olarak alır.
Çoğu kişinin atladığı kısım: splash ekranından fazlasını senaryoya dahil edin. Gerçek darboğaz Room’dan gelen veriyle ilk liste render’ıysa ya da bir widget’ın ilk provider çağrısıysa, bu etkileşimi collect bloğuna ekleyin. Sadece onCreate()’i kapsayan bir profil gerçek kazancın çoğunu kaçırır.
Kazancı dürüstçe ölçmek
Bir kronometreye ve baş parmağınıza güvenmeyin. Ayrı bir macrobenchmark testinde StartupTimingMetric kullanın, profili olmayan ve olan bir derlemeye karşı çalıştırın ve gürültünün her iki yönde de ortalanacağı kadar çok iterasyonda medyanları karşılaştırın:
@Test
fun startupCompilationModes() {
benchmarkRule.measureRepeated(
packageName = "com.mfk.hydrame",
metrics = listOf(StartupTimingMetric()),
iterations = 10,
startupMode = StartupMode.COLD,
compilationMode = CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require),
) {
pressHome()
startActivityAndWait()
}
}
Referans karşılaştırma çalıştırması için compilationMode’u CompilationMode.None() ile değiştirin. On iterasyon makul bir alt sınırdır — cihaz termal durumu ve arka plan süreçleri, üç çalıştırmanın her iki yönde de sizi yanıltmasına yetecek kadar gürültü ekler.
Baseline Profiles’ın düzeltmediği şeyler
Bunlar başlatma işini gerçekten azaltmanın yerine geçmez. Application.onCreate()’iniz üç SDK başlatıyor, veritabanını hevesle açıyor ve ağır bir ilk ekranı inflate ediyorsa, profil bu işi yorumlamak için daha hızlı hale getirir — daha az iş olmasını sağlamaz. Kazançlar şunlarla birlikte büyür, onların yerine geçmez:
- Kritik olmayan başlatmayı ertelemek. İlk kare için gerekli olmayan her şey — analitik SDK’ları, kritik olmayan WorkManager planlaması, uzak yapılandırma çekmeleri —
onCreate()içinde değil, UI görünür olduktan sonra arka planda çalıştırılmalı. - Release derlemelerinde R8 full mode. Bytecode’u küçültmek ve optimize etmek, profil olsun olmasın, ART’ın baştan geçmesi gereken kod miktarını azaltır demektir.
- Hevesli singleton’lar yerine tembel (lazy) olanlar. İlk DAO erişiminde başlatılan
by lazybir veritabanı örneği, ilk ekran ona henüz ihtiyaç duymuyorsa başlatmada size hiçbir maliyete mal olmaz.
Bunu Hydrame’in ana ekran widget’ını yaparken keşfettim: widget’ın kendi soğuk başlatması (ayrı bir süreç bağlamı, dayanacak sıcak bir Application yok), profilde widget’ın kod yolunun hiçbiri olmadığı için uygulamanınkinden daha yavaştı. Macrobenchmark script’ine sadece uygulamanın ana activity’sini değil, widget’a özel bir senaryo eklemek bu farkın çoğunu kapattı.
Bu öğleden sonrasına ne zaman değer
Uygulamanız zaten hızlıysa, Baseline Profile güzel bir ek özelliktir. Soğuk başlatma, Play Console’un vitals panosunda sarıda oturan tek metrikse, genellikle harcayabileceğiniz en yüksek getirili öğleden sonrasıdır: mimari değişiklik yok, özellik riski yok, sadece oluşturulmuş bir dosya ve bir Gradle eklentisi. Her sürüm için gerçek kritik yollarınızdan bir kez oluşturun, bir yeniden tasarımın profilin kapsadığı şeyi sessizce aşmaması için Macrobenchmark testini CI’da tutun ve soğuk başlatma sayısına başka bir regresyona davrandığınız gibi davranın — izlediğiniz, bir kez düzeltip unuttuğunuz bir şey değil.
// İlgili okumalar
Günlükten dahası
2026'da Jetpack DataStore: tek bir ayarı bile kaybetmeden SharedPreferences'tan geçiş
SharedPreferences'tan Jetpack DataStore'a geçiş için pratik bir Android rehberi — asenkron tuzaklar, mevcut değerleri koruyan migrasyon yolu ve bunu nasıl test edeceğiniz.
Mintly'i inşa etmek: Android süreci öldürmek isterken bir odak zamanlayıcısını doğru tutmak
Çalışan bir Pomodoro zamanlayıcısının, tek seferlik bir hatırlatıcıdan daha zor bir güvenilirlik sorunu var. İşte Mintly'in ön plan servisi ve duvar saati bitiş zamanıyla Doze, süreç ölümü ve ekran kapalıyken oluşan kaymayı nasıl atlattığı.
Android'de ML Kit ile barkod tarama (2026): Stocky bir kiler ürününü bir saniyeden kısa sürede nasıl ekliyor
ML Kit ve CameraX ile cihaz üzerinde barkod tarama için pratik bir 2026 rehberi: format ayarı, çevrimdışı ürün arama ve bir kiler uygulamasının arkasındaki kısmi kullanım matematiği.