Secara default, R8 melakukan banyak pengoptimalan untuk meningkatkan performa dan ukuran, tetapi pengoptimalan mungkin tidak langsung berfungsi untuk aplikasi Anda. Jika Anda mengaktifkan R8 (atau mengaktifkan mode penuh) di aplikasi besar untuk pertama kalinya, coba terapkan pengoptimalan secara bertahap: nonaktifkan obfuscation untuk sementara dan aktifkan R8 untuk sebagian kode dalam satu waktu, bukan untuk semua kode di aplikasi Anda. Sebaiknya gunakan pendekatan inkremental ini selama pengembangan lokal, tetapi Anda juga dapat menggunakannya selama pengujian QA internal atau bahkan dalam produksi sebagai peluncuran bertahap. Langkah-langkah yang Anda ambil bergantung pada linimasa yang Anda inginkan dan keyakinan Anda terhadap cakupan pengujian pra-rilis.
Membatasi pengoptimalan
R8 melakukan banyak jenis pengoptimalan, termasuk menghapus kode, menulis ulang kode, dan menghapus resource. Berikut adalah beberapa deskripsi umum tentang jenis pengoptimalan:
- Penyingkatan kode (atau tree shaking): menghapus kode yang tidak direferensikan
- Obfuscation (atau minifikasi ID): mempersingkat nama class dan metode
- Pengoptimalan: menulis ulang kode, misalnya inlining
Untuk mengurangi kemungkinan error, Anda dapat memulai dengan mengaktifkan hanya beberapa pengoptimalan ini.
Hanya mengaktifkan penghapusan kode yang tidak terpakai
Penyingkatan kode, yang juga dikenal sebagai tree shaking, menghapus kode yang tampaknya tidak direferensikan. Sebaiknya mulai dengan tree shaking saja, karena ini adalah cara yang paling mudah.
Untuk mengaktifkan tree shaking saja, tambahkan kode berikut ke
file proguard-rules.pro Anda untuk menonaktifkan jenis pengoptimalan lainnya. Menonaktifkan pengaburan sangat penting karena membuat stack trace jauh lebih mudah dibaca.
-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization
Pada akhirnya, Anda tidak ingin mengirimkan konfigurasi ini, karena secara drastis membatasi kemampuan R8 untuk mengoptimalkan kode, tetapi ini adalah titik awal yang bagus saat mengadopsi R8 untuk pertama kalinya dalam codebase besar dengan masalah yang harus diperbaiki.
Menggunakan mode kompatibilitas
Secara default, R8 berjalan dalam mode penuh. Mode penuh memberikan peningkatan performa dan penghematan ukuran yang signifikan, tetapi Anda dapat menonaktifkannya untuk sementara dan menggunakan mode kompatibilitas sebagai gantinya saat mengaktifkan pengecilan untuk pertama kalinya.
Untuk menggunakan mode kompatibilitas, gunakan setelan berikut di file gradle.properties Anda:
android.enableR8.fullMode = false // Use temporarily to disable full mode
Mengaktifkan pengoptimalan lainnya
Setelah mengonfirmasi bahwa penghilangan kode yang tidak terpakai berfungsi untuk aplikasi Anda, Anda dapat menghapus setelan sebelumnya untuk mengaktifkan kembali pengaburan, pengoptimalan, dan mode penuh R8. Perhatikan bahwa pengaburan dapat mempersulit proses debug, itulah sebabnya kami merekomendasikan untuk mengatasi masalah penghilangan kode yang tidak terpakai terlebih dahulu.
Untuk mengetahui informasi selengkapnya tentang cara men-deobfuscate stack trace, lihat Memulihkan stack trace asli.
Membatasi cakupan pengoptimalan
Build yang dioptimalkan sepenuhnya akan mengoptimalkan semua kode di setiap library dan paket, sehingga masalah pada R8 sering terjadi saat Anda pertama kali mengaktifkannya. Jika Anda menemukan masalah pengoptimalan di salah satu bagian aplikasi, jangan nonaktifkan R8 sepenuhnya atau Anda akan kehilangan manfaat di bagian lain. Sebagai gantinya, nonaktifkan R8 untuk sementara hanya di bagian aplikasi yang menyebabkan masalah.
Menggunakan aturan penyimpanan di seluruh paket
Sebaiknya gunakan aturan keep di seluruh paket sebagai cara untuk menonaktifkan R8 sementara di bagian aplikasi Anda. Anda harus selalu kembali untuk memperbaiki masalah pengoptimalan ini nanti; ini umumnya merupakan solusi sementara untuk mengatasi area masalah.
Misalnya, jika sebagian aplikasi Anda banyak menggunakan Gson dan menyebabkan masalah pada
pengoptimalan, perbaikan yang ideal adalah menambahkan lebih banyak
aturan penyimpanan yang ditargetkan atau beralih ke solusi codegen. Namun,
untuk berhenti memblokir pengoptimalan aplikasi lainnya, Anda dapat menempatkan kode yang menentukan
jenis Gson dalam subpaket khusus, dan menambahkan aturan seperti ini ke
file proguard-rules.pro:
-keep class com.myapp.json.** { *; }
Jika beberapa library yang Anda gunakan memiliki refleksi ke komponen internal, Anda juga dapat menambahkan aturan keep untuk seluruh library. Anda perlu memeriksa kode atau JAR/AAR library untuk menemukan paket yang sesuai untuk dipertahankan. Sekali lagi, hal ini tidak direkomendasikan untuk dipertahankan dalam jangka panjang, tetapi dapat menghentikan pemblokiran pengoptimalan aplikasi lainnya:
-keep class com.somelibrary.** { *; }
Menghapus aturan keep di seluruh paket
Setelah aplikasi Anda berfungsi dengan benar menggunakan aturan keep seluruh paket, Anda harus kembali dan menambahkan aturan keep yang ditargetkan, atau menghapus penggunaan refleksi atau library yang memerlukan aturan keep sejak awal.
Misalnya, mempertahankan semua aturan yang memperluas class tertentu sangat umum di AndroidX untuk mempertahankan hanya class yang relevan. Secara umum, refleksi hanya boleh menargetkan class atau metode yang memperluas class abstrak tertentu, mengimplementasikan antarmuka tertentu, atau ke dalam class dengan anotasi runtime tertentu. Masing-masing adalah cara yang didukung untuk menentukan aturan penyimpanan sehingga Anda tidak memerlukan aturan penyimpanan di seluruh paket dalam aplikasi akhir yang dioptimalkan sepenuhnya.
Jika refleksi ada di codebase Anda sendiri, Anda dapat mengganti aturan keep di seluruh paket dengan Jetpack Keep. Aturan yang dihasilkan bersifat kondisional: R8 mempertahankan target panggilan reflektif hanya jika R8 juga mempertahankan kode yang melakukan panggilan. Untuk memigrasikan paket, gunakan pemeriksaan lint Jetpack Keep untuk menemukan dan menganotasi panggilan reflektifnya, lalu hapus aturan seluruh paket.