Optimizasyonları kademeli olarak kullanmaya başlayın

R8, performans ve boyutu iyileştirmek için varsayılan olarak birçok optimizasyon yapar ancak bu optimizasyonlar uygulamanızda hemen çalışmayabilir. Büyük bir uygulamada ilk kez R8'i etkinleştiriyorsanız (veya tam modu etkinleştiriyorsanız) optimizasyonları kademeli olarak uygulamayı deneyin: Karartmayı geçici olarak devre dışı bırakın ve R8'i uygulamanızdaki tüm kod için değil, kodun belirli bölümleri için etkinleştirin. Bu kademeli yaklaşımı yerel geliştirme sırasında kullanmanızı öneririz ancak dahili kalite güvencesi testi sırasında veya hatta üretimde kademeli bir kullanıma sunma olarak da kullanabilirsiniz. Tam olarak hangi adımları uygulayacağınız, istediğiniz zaman çizelgesine ve yayın öncesi test kapsamınıza olan güveninize bağlıdır.

Optimizasyonları sınırlama

R8, kod kaldırma, kodu yeniden yazma ve kaynak kaldırma gibi birçok optimizasyon türü gerçekleştirir. Aşağıda, optimizasyon türleriyle ilgili bazı genel açıklamalar verilmiştir:

  • Kod daraltma (veya ağaç sallama): Referans verilmeyen kodu kaldırır.
  • Karartma (veya tanımlayıcı sadeleştirme): Sınıf ve yöntem adlarını kısaltır.
  • Optimizasyon: Kodu yeniden yazar (ör. satır içi işleme)

Hata olasılığını azaltmak için bu optimizasyonlardan yalnızca bazılarını etkinleştirerek başlayabilirsiniz.

Yalnızca ağaç sallamayı etkinleştirme

Ağaç sallama olarak da bilinen kod daraltma, referans verilmemiş gibi görünen kodları kaldırır. En basit yöntem olduğundan yalnızca tree shaking ile başlamanızı öneririz.

Yalnızca tree shaking'i etkinleştirmek için diğer optimizasyon türlerini devre dışı bırakmak üzere proguard-rules.pro dosyanıza aşağıdakileri ekleyin. Kod karartmayı devre dışı bırakmak, yığın izlemelerinin (stack trace) çok daha kolay okunabilmesini sağladığı için önemlidir.

-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization

Sonuç olarak, R8'in kodu optimize etme yeteneğini önemli ölçüde sınırladığı için bu yapılandırmayı yayınlamak istemezsiniz. Ancak, düzeltilmesi gereken sorunları olan büyük bir kod tabanında R8'i ilk kez kullanmaya başlarken bu yapılandırma harika bir başlangıç noktasıdır.

Uyumluluk modunu kullan

R8 varsayılan olarak tam modda çalışır. Tam mod, performansı önemli ölçüde artırır ve boyut tasarrufu sağlar. Ancak küçültmeyi ilk kez etkinleştirirken bu modu geçici olarak devre dışı bırakıp bunun yerine uyumluluk modunu kullanabilirsiniz.

Uyumluluk modunu kullanmak için gradle.properties dosyanızda aşağıdaki ayarı kullanın:

android.enableR8.fullMode = false // Use temporarily to disable full mode

Diğer optimizasyonları etkinleştirme

Tree shaking'in uygulamanızda çalıştığını onayladıktan sonra, kod karartma, optimizasyon ve R8 tam modunu yeniden etkinleştirmek için önceki ayarları kaldırabilirsiniz. Karartmanın hata ayıklamayı zorlaştırabileceğini unutmayın. Bu nedenle, önce gereksiz kodları kaldırma sorunlarını gidermenizi öneririz.

Yığın izlemelerin kodunu gösterme hakkında daha fazla bilgi için Orijinal yığın izlemeyi kurtarma başlıklı makaleyi inceleyin.

Optimizasyon kapsamını sınırlama

Tamamen optimize edilmiş bir derleme, her kitaplık ve paketteki tüm kodları optimize eder. Bu nedenle, R8'i ilk etkinleştirdiğinizde sorunlarla karşılaşmanız normaldir. Uygulamanın bir bölümünde optimizasyonla ilgili bir sorunla karşılaşırsanız R8'i tamamen devre dışı bırakmayın. Aksi takdirde diğer bölümlerdeki avantajlardan yararlanamazsınız. Bunun yerine, R8'i geçici olarak yalnızca uygulamanızın sorunlara neden olan bölümlerinde devre dışı bırakın.

Paket genelinde saklama kurallarını kullanma

Uygulamanızın bazı bölümlerinde R8'i geçici olarak devre dışı bırakmak için paket genelinde saklama kuralları kullanmanızı öneririz. Bu optimizasyon sorunlarını daha sonra düzeltmek için her zaman geri dönmeniz gerekir. Bu, genellikle sorunlu alanları geçici olarak çözmek için kullanılan bir çözümdür.

Örneğin, uygulamanızın bir bölümünde Gson yoğun bir şekilde kullanılıyorsa ve optimizasyonla ilgili sorunlara neden oluyorsa ideal çözüm, daha fazla hedefli tutma kuralı eklemek veya kod oluşturma çözümüne geçmektir. Ancak uygulamanın geri kalanının optimizasyonunun engellenmesini önlemek için Gson türlerinizi tanımlayan kodu özel bir alt pakete yerleştirebilir ve proguard-rules.pro dosyanıza aşağıdaki gibi bir kural ekleyebilirsiniz:

-keep class com.myapp.json.** { *; }

Kullandığınız bir kitaplıkta reflection özelliği varsa benzer şekilde tüm kitaplık için bir saklama kuralı ekleyebilirsiniz. Tutulacak uygun paketi bulmak için kitaplığın kodunu veya JAR/AAR'yi incelemeniz gerekir. Bu yöntem, uzun vadede önerilmese de uygulamanın geri kalanının optimizasyonunun engelini kaldırabilir:

-keep class com.somelibrary.** { *; }

Paket genelindeki saklama kurallarını kaldırma

Uygulamanız paket genelinde saklama kurallarıyla doğru şekilde çalıştıktan sonra geri dönüp hedefli saklama kuralları eklemeniz veya saklama kuralını gerektiren yansıtma kullanımını ya da kitaplığı kaldırmanız gerekir.

Örneğin, AndroidX'te yalnızca alakalı sınıfları tutmak için belirli bir sınıfı genişleten tüm kuralları tutmak son derece yaygındır. Genel olarak, yansıma yalnızca belirli soyut sınıfları genişleten, belirli arayüzleri uygulayan sınıfları veya yöntemleri ya da belirli bir çalışma zamanı ek açıklamasına sahip sınıfları hedeflemelidir. Bunların her biri, saklama kurallarını tanımlamanın desteklenen yöntemleridir. Böylece, tamamen optimize edilmiş nihai uygulamanızda paket genelinde saklama kurallarına ihtiyacınız olmaz.

Kendi kod tabanınızda yansıma varsa paket genelindeki saklama kurallarını Jetpack Keep ile değiştirebilirsiniz. Oluşturulan kurallar koşulludur: R8, yansıtmalı çağrının hedefini yalnızca çağrıyı yapan kodu da tutuyorsa tutar. Bir paketi taşımak için Jetpack Keep lint kontrollerini kullanarak yansıtıcı çağrılarını bulun ve bunlara açıklama ekleyin, ardından paket genelindeki kuralı kaldırın.