Derleme hızınızı optimize etme

Uzun derleme süreleri, geliştirme sürecinizi yavaşlatır. Bu sayfada, derleme hızı sorunlarını çözmeye yardımcı olacak bazı teknikler sunulmaktadır.

Uygulamanızın derleme hızını iyileştirme genel süreci şu şekildedir:

  1. Çoğu Android Studio projesinin avantajlarından hemen yararlanabilecek birkaç adımı uygulayarak derleme yapılandırmanızı optimize edin.
  2. Projenize veya iş istasyonunuza özgü olabilecek bazı zorlu performans sorunlarını tespit edip teşhis etmek için derlemenizin profilini oluşturun.

Uygulamanızı geliştirirken mümkün olduğunda Android 7.0 (API düzeyi 24) veya sonraki sürümleri çalıştıran bir cihaza dağıtın. Android platformunun daha yeni sürümlerinde, uygulamanızın güncellenmesini sağlayan Android Runtime (ART) ve birden fazla DEX dosyasına yönelik yerel destek gibi daha iyi mekanizmalar sunulmaktadır.

Not: İlk temiz derlemenizden sonra, hem temiz hem de artımlı sonraki derlemelerin, bu sayfada açıklanan optimizasyonların hiçbirini kullanmadan bile çok daha hızlı performans gösterdiğini fark edebilirsiniz. Bunun nedeni, Gradle arka plan programının, diğer JVM işlemlerine benzer şekilde performans artışına yönelik bir "hazırlanma" dönemine sahip olmasıdır.

Derleme yapılandırmanızı optimize etme

Android Studio projenizin derleme hızını artırmak için bu ipuçlarını uygulayın.

Araçlarınızı güncel tutun

Android araçları, neredeyse her güncellemede derleme optimizasyonları ve yeni özellikler alır. Bu sayfadaki bazı ipuçlarında en son sürümü kullandığınız varsayılmaktadır. En son optimizasyonlardan yararlanmak için aşağıdakileri güncel tutun:

Kapt yerine önemli satış sağlayıcıyı kullan

Kotlin Ek Açıklama İşleme Aracı (kapt), Kotlin Symbol İşlemciden (KSP) çok daha yavaştır. Ek açıklamalı Kotlin kaynağı yazıyorsanız ve KSP'yi destekleyen ek açıklamaları işleyen (Oda gibi) araçlar kullanıyorsanız KSP'ye geçiş yapmanız gerekir.

Gereksiz kaynakları derlemekten kaçının

Test etmediğiniz kaynakları derlemekten ve paketlemekten kaçının (ör. ek dil yerelleştirmeleri ve ekran yoğunluğu kaynakları). Bunun yerine, aşağıdaki örnekte gösterildiği gibi "dev" tarzınız için yalnızca bir dil kaynağı ve ekran yoğunluğu belirtin:

Modern

android {
    ...
    productFlavors {
        dev {
            ...
            // The following configuration limits the "dev" flavor to using
            // English stringresources and xxhdpi screen-density resources.
            resourceConfigurations "en", "xxhdpi"
        }
        ...
    }
}

Kotlin

android {
    ...
    productFlavors {
        create("dev") {
            ...
            // The following configuration limits the "dev" flavor to using
            // English stringresources and xxhdpi screen-density resources.
            resourceConfigurations("en", "xxhdpi")
        }
        ...
    }
}

Gradle Plugin Portal'ı en son kullanarak deneme yapma

Android'de tüm eklentiler google() ve mavenCentral() depolarında bulunur. Ancak derlemeniz, gradlePluginPortal() hizmetini kullanarak çözülen üçüncü taraf eklentileri gerektirebilir.

Gradle, depoları bildirildikleri sırayla arar. Bu nedenle, listelenen depolar eklentilerin çoğunu içeriyorsa derleme performansı artar. Bu nedenle, settings.gradle dosyanızdaki depo bloğuna en son yerleştirerek gradlePluginPortal() girişiyle denemeler yapın. Çoğu durumda bu, gereksiz eklenti aramalarının sayısını en aza indirir ve derleme hızınızı artırır.

Gradle'ın birden fazla depoda nasıl gezindiği hakkında daha fazla bilgi için Gradle dokümanlarındaki Birden fazla depo tanımlama bölümüne bakın.

Hata ayıklama derlemenizle statik derleme yapılandırması değerleri kullanma

Hata ayıklama derleme türünüze ilişkin manifest dosyasına veya kaynak dosyalarına giden mülkler için her zaman statik değerler kullanın.

Dinamik sürüm kodlarını, sürüm adlarını, kaynakları veya manifest dosyasını değiştiren diğer derleme mantıklarını kullanmak, her değişiklik çalıştırmak istediğinizde tam bir uygulama derlemesinin kullanılmasını gerektirir. Asıl değişiklik için başka şekilde yalnızca çalışır durumda değiştirme yapılması gerekebilir. Derleme yapılandırmanız bu tür dinamik özellikler gerektiriyorsa aşağıdaki örnekte gösterildiği gibi bu özellikleri sürüm derlemesi varyantlarınıza ayırın ve hata ayıklama derlemeleriniz için değerleri statik tutun:

  ...
  // Use a filter to apply onVariants() to a subset of the variants.
  onVariants(selector().withBuildType("release")) { variant ->
      // Because an app module can have multiple outputs when using multi-APK, versionCode
      // is only available on the variant output.
      // Gather the output when we are in single mode and there is no multi-APK.
      val mainOutput = variant.outputs.single { it.outputType == OutputType.SINGLE }

      // Create the version code generating task.
      val versionCodeTask = project.tasks.register("computeVersionCodeFor${variant.name}", VersionCodeTask::class.java) {
          it.outputFile.set(project.layout.buildDirectory.file("versionCode${variant.name}.txt"))
      }

      // Wire the version code from the task output.
      // map will create a lazy Provider that:
      // 1. Runs just before the consumer(s), ensuring that the producer (VersionCodeTask) has run
      //    and therefore the file is created.
      // 2. Contains task dependency information so that the consumer(s) run after the producer.
      mainOutput.versionCode.set(versionCodeTask.flatMap { it.outputFile.map { it.asFile.readText().toInt() } })
  }
  ...

  abstract class VersionCodeTask : DefaultTask() {

    @get:OutputFile
    abstract val outputFile: RegularFileProperty

    @TaskAction
    fun action() {
        outputFile.get().asFile.writeText("1.1.1")
    }
  }

Projenizde dinamik sürüm kodunu nasıl ayarlayacağınızı öğrenmek için GitHub'daki setVersionsFromTask tarifine bakın.

Statik bağımlılık sürümlerini kullanın

build.gradle dosyalarınızda bağımlılıkları bildirirken dinamik sürüm numaraları (sonunda artı işareti ('com.android.tools.build:gradle:2.+' gibi) bulunanlar) kullanmaktan kaçının. Dinamik sürüm numaralarının kullanılması beklenmedik sürüm güncellemelerine, sürüm farklılıklarının çözümlenmesinde zorluklara ve Gradle'ın güncelleme kontrolünün neden olduğu derlemelerin yavaşlamasına neden olabilir. Bunun yerine statik sürüm numaraları kullanın.

Kitaplık modülleri oluşturma

Uygulamanızda, Android kitaplık modülüne dönüştürebileceğiniz kodu arayın. Kodunuzu bu şekilde modülerleştirerek derleme sistemi yalnızca değiştirdiğiniz modülleri derleyebilir ve gelecekteki derlemeler için bu çıkışları önbelleğe alabilir. Modülerleştirme, bu optimizasyonu etkinleştirdiğinizde paralel proje yürütmeyi de daha etkili hale getirir.

Özel derleme mantığı için görev oluşturma

Derleme profili oluşturduktan sonra derleme profili, derleme süresinin nispeten uzun bir bölümünün **Projeleri Yapılandırma** aşamasında harcandığını gösteriyorsa build.gradle komut dosyalarınızı inceleyin ve özel bir Gradle görevine dahil edilecek kodu arayın. Bazı derleme mantığını göreve taşıyarak görevin yalnızca gerektiğinde çalışmasını, sonuçların sonraki derlemeler için önbelleğe alınabilmesini ve paralel proje yürütmeyi etkinleştirirseniz derleme mantığının paralel olarak çalışmaya uygun hale gelmesini sağlarsınız. Özel derleme mantığı için taks hakkında daha fazla bilgi edinmek istiyorsanız resmi Gradle belgelerini okuyun.

İpucu: Derlemeniz çok sayıda özel görev içeriyorsa özel görev sınıfları oluşturarak build.gradle dosyalarınızı düzenlemek isteyebilirsiniz. Sınıflarınızı project-root/buildSrc/src/main/groovy/ dizinine ekleyin. Gradle, projenizdeki tüm build.gradle dosyaları için bu sınıfları sınıf yoluna otomatik olarak ekler.

Resimleri WebP'ye dönüştürün

WebP, kayıplı sıkıştırma (JPEG gibi) ve şeffaflık (PN gibi) sağlayan bir resim dosyası biçimidir. WebP, JPEG veya PNG'den daha iyi sıkıştırma sağlayabilir.

Derleme süresinde sıkıştırma yapmak zorunda kalmadan görüntü dosyasının boyutunu küçültmek, özellikle uygulamanız çok fazla görüntü kaynağı kullanıyorsa derlemelerinizi hızlandırabilir. Ancak WebP resimlerinin sıkıştırmasını açarken cihazın CPU kullanımında küçük bir artış fark edebilirsiniz. Android Studio'yu kullanarak resimlerinizi kolayca WebP'ye dönüştürün.

PNG işini devre dışı bırak

PNP resimlerinizi WebP'ye dönüştürmezseniz uygulamanızı her derlediğinizde otomatik resim sıkıştırmayı devre dışı bırakarak derlemenizi hızlandırabilirsiniz.

Android Gradle eklentisi 3.0.0 veya sonraki bir sürümü kullanıyorsanız PNG işleme, "hata ayıklama" derleme türü için varsayılan olarak devre dışıdır. Diğer derleme türlerinde bu optimizasyonu devre dışı bırakmak için aşağıdakileri build.gradle dosyanıza ekleyin:

Modern

android {
    buildTypes {
        release {
            // Disables PNG crunching for the "release" build type.
            crunchPngs false
        }
    }
}

Kotlin

android {
    buildTypes {
        getByName("release") {
            // Disables PNG crunching for the "release" build type.
            isCrunchPngs = false
        }
    }
}

Derleme türleri veya ürün çeşitleri bu özelliği tanımlamadığından, uygulamanızın sürüm sürümünü oluştururken bu özelliği manuel olarak true şeklinde ayarlamanız gerekir.

JVM paralel çöp toplayıcı ile denemeler yapın

Gradle tarafından kullanılan optimum JVM çöp toplayıcısı yapılandırılarak derleme performansı geliştirilebilir. JDK 8 varsayılan olarak paralel çöp toplayıcıyı kullanacak şekilde yapılandırılırken JDK 9 ve sonraki sürümler G1 çöp toplayıcıyı kullanacak şekilde yapılandırılır.

Derleme performansını potansiyel olarak artırmak için Gradle derlemelerinizi paralel çöp toplayıcı ile test etmenizi öneririz. gradle.properties içinde aşağıdakileri ayarlayın:

org.gradle.jvmargs=-XX:+UseParallelGC

Bu alanda önceden ayarlanmış başka seçenekler varsa yeni bir seçenek ekleyin:

org.gradle.jvmargs=-Xmx1536m -XX:+UseParallelGC

Derleme hızını farklı yapılandırmalarla ölçmek için Derlemenizin profilini oluşturma bölümüne bakın.

JVM yığın boyutunu artır

Yavaş derlemeler gözlemlerseniz ve özellikle atık toplama işleminin, Derleme Analiz Aracı sonuçlarınızdaki derleme süresinin% 15'ten fazlasını aldığını fark ederseniz Java Sanal Makinesi (JVM) yığın boyutunu artırmanız gerekir. gradle.properties dosyasında, sınırı aşağıdaki örnekte gösterildiği gibi 4, 6 veya 8 gigabayt olarak ayarlayın:

org.gradle.jvmargs=-Xmx6g

Sonra, derleme hızında iyileşme olup olmadığını test edin. Optimum yığın boyutunu belirlemenin en kolay yolu, sınırı biraz artırmak ve ardından yeterli derleme hızı iyileştirmesi olup olmadığını test etmektir.

JVM paralel çöp toplayıcı da kullanıyorsanız çizginin tamamı aşağıdaki gibi görünmelidir:

org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g

HeapDumpOnOutOfMemoryError işaretini açarak JVM bellek hatalarını analiz edebilirsiniz. Bunu yaptığınızda JVM, bellek azaldığında bir yığın dökümü oluşturur.

Geçişsiz R sınıflarını kullanma

Birden fazla modül içeren uygulamalarda daha hızlı derlemeler elde etmek için geçişsiz R sınıflarını kullanın. Bu sayede her modülün R sınıfının, bağımlılıklarından referans çekmeden yalnızca kendi kaynaklarına referanslar içermesini sağlayarak kaynak yinelemelerinin önlenmesine yardımcı olursunuz. Bu, derlemelerin daha hızlı olmasını ve derlemeden kaçınmanın avantajlarını sağlar. Bu, Android Gradle eklentisi 8.0.0 ve sonraki sürümlerde varsayılan davranıştır.

Android Studio Bumblebee'den başlayarak, geçişsiz R sınıfları yeni projeler için varsayılan olarak etkindir. Android Studio'nun önceki sürümleriyle oluşturulan projeleri, Yeniden düzenleme > Geçişsiz R Sınıflarına Taşı'ya giderek geçişsiz R sınıflarını kullanacak şekilde güncelleyin.

Uygulama kaynakları ve R sınıfı hakkında daha fazla bilgi edinmek için Uygulama kaynaklarına genel bakış bölümüne bakın.

Sabit olmayan R sınıflarını kullanma

Java derlemesinin artımlılığını iyileştirmek ve kaynakların daha hassas bir şekilde küçültülmesini sağlamak için uygulamalarda ve testlerde sabit olmayan R sınıfı alanları kullanın. Uygulama veya test için APK'yı söz konusu kitaplığa bağlı olarak paketlerken kaynaklar numaralandırılır. Bu nedenle, R sınıf alanları kitaplıklarda her zaman sabit değildir. Bu, Android Gradle Plugin 8.0.0 ve sonraki sürümlerde varsayılan davranıştır.

Jetifier işaretini devre dışı bırak

Çoğu proje doğrudan AndroidX kitaplıklarını kullandığından, daha iyi derleme performansı için Jetifier işaretini kaldırabilirsiniz. Jetifier işaretini kaldırmak için gradle.properties dosyanızda android.enableJetifier=false değerini ayarlayın.

Derleme Analiz Aracı, projenizin daha iyi derleme performansına sahip olması ve bakımı yapılmayan Android Destek kitaplıklarından taşınması için işaretin güvenli bir şekilde kaldırılıp kaldırılmayacağını kontrol edebilir. Derleme Analiz Aracı hakkında daha fazla bilgi edinmek için Derleme performansı sorunlarını giderme bölümüne bakın.

Yapılandırma önbelleğini kullanma

Yapılandırma önbelleği, Gradle'ın derleme görevleri grafiğiyle ilgili bilgileri kaydetmesine ve sonraki derlemelerde yeniden kullanmasına olanak tanır. Böylece Gradle'ın derlemenin tamamını yeniden yapılandırmasına gerek kalmaz.

Yapılandırma önbelleğini etkinleştirmek için şu adımları uygulayın:

  1. Tüm proje eklentilerinin uyumlu olup olmadığını kontrol edin.

    Projenizin yapılandırma önbelleğiyle uyumlu olup olmadığını kontrol etmek için Derleme Analiz Aracı'nı kullanın. Derleme Analiz Aracı, özelliğin projede etkinleştirilip etkinleştirilemeyeceğini belirlemek için bir dizi test derlemesi çalıştırır. Desteklenen eklentilerin listesi için 13490 numaralı sorunu inceleyin.

  2. gradle.properties dosyasına aşağıdaki kodu ekleyin:

      org.gradle.configuration-cache=true
      # Use this flag carefully, in case some of the plugins are not fully compatible.
      org.gradle.configuration-cache.problems=warn

Yapılandırma önbelleği etkinleştirildiğinde projenizi ilk kez çalıştırdığınızda derleme çıktısında Calculating task graph as no configuration cache is available for tasks yazar. Sonraki çalıştırmalar sırasında derleme çıkışı Reusing configuration cache olarak görünür.

Yapılandırma önbelleği hakkında daha fazla bilgi edinmek için Yapılandırma önbelleğiyle ilgili ayrıntılı inceleme başlıklı blog yayınına ve yapılandırma önbelleği ile ilgili Gradle dokümanlarına göz atın.

Gradle 8.1 ve Android Gradle Eklentisi 8.1'de sunulan yapılandırma önbelleği sorunları

Yapılandırma önbelleği, Gradle 8.1'de stabil hale geldi ve dosya API izlemesi kullanıma sunuldu. File.exists(), File.isDirectory() ve File.list() gibi çağrılar, yapılandırma giriş dosyalarını izlemek için Gradle tarafından kaydedilir.

Android Gradle Plugin (AGP) 8.1, Gradle'ın önbellek girişi olarak kabul etmemesi gereken bazı dosyalar için bu File API'lerini kullanır. Bu durum, Gradle 8.1 ve sonraki sürümlerle birlikte kullanıldığında önbelleğin ek geçersiz kılınmasını tetikleyerek derleme performansını yavaşlatır. Aşağıdakiler, AGP 8.1'de önbellek girişleri olarak ele alınır:

Giriş Sorun İzleyici Düzeltildiği yer
$GRADLE_USER_HOME/android/FakeDependency.jar Sorun #289232054 AGP 8,2
cmake çıktısı Sorun No. 287676077 AGP 8,2
$GRADLE_USER_HOME/.android/analytics.settings Sorun #278767328 AGP 8,3

Bu API'leri veya bu API'leri kullanan bir eklentiyi kullanırsanız bu API'leri kullanan bazı derleme mantığı, önbellek geçersiz kılma işlemlerini tetikleyebilir. Bu nedenle, derleme sürenizde bir regresyonla karşılaşabilirsiniz. Bu kalıplar ve derleme mantığının nasıl düzeltileceği ve dosya API izlemesinin geçici olarak nasıl devre dışı bırakılacağıyla ilgili açıklamalar için lütfen Derleme yapılandırması giriş izlemedeki iyileştirmeler bölümüne bakın.