مقایسه R8 باProguard
Proguard برای همه توسعه دهندگان اندروید آشنا به نظر می رسد. ما از آن برای کاهش اندازه، بهبود عملکرد برنامه با کاهش منابع استفاده نشده استفاده می کنیم.
گوگل R8 را به عنوان جایگزینی برای Proguard منتشر کرد تا به توسعه دهندگان کمک کند تا کد را با خروجی تولید شده بهتر (APK) کوچک (shrink) کنند. آنها در مقایسه با Proguard بسیار سریعتر به نظر می رسند.
R8 چیست؟
R8 ابزاری است که byte code جاوا ما را به یک کد dex بهینه تبدیل می کند. در تمام برنامه تکرار می شود و سپس مانند حذف کلاس های استفاده نشده، متدها و غیره بهینه سازی می کند. در زمان کامپایل اجرا می شود و به ما کمک می کند تا سایز Build را کاهش دهیم و برنامه خود را ایمن تر کنیم. R8 از قوانین Proguard برای تغییر behavior پیش فرض خود استفاده می کند.
Shrink در R8 چگونه کار می کند؟
در حین بهینه سازی کد، R8 کد برنامه ما را کاهش می دهد و سپس سایز APK نیزکاهش می یابد.
برای کاهش سایز APK، ما سه تکنیک مختلف داریم:
Shrinking یا Tree Shaking: Shrinking فرآیند حذف کدهای غیرقابل دسترس از پروژه اندروید ما است. R8 برای خلاص شدن از شر کدهای غیرقابل دسترس، آنالیز static را انجام می دهد و object نمونه سازی نشده را حذف می کند.
بهینه سازی(Optimization): جهت بهینه سازی کد برای size استفاده می شود. که شامل حذف کد مرده(dead code)، حذف آرگومان استفاده نشده، درونسازی انتخابی (selective inlining)، ادغام کلاس(class merging) و غیره است.
تغییر نام شناسه: در این فرآیند، نام کلاس و نام متغیرهای دیگر را مبهم (obfuscate)می کنیم. به عنوان مثال، اگر نام کلاس “MainActivity” باشد، آنگاه به “a” یا چیز دیگری تبدیل می شود اما از نظر اندازه کوچکتر مبهم می شود.
چگونه درR8 ، Shrink (کوچک شدن) را در اپلیکیشن خود فعال کنیم؟
R8 به طور پیش فرض در برنامه ما وجود دارد، اما برای فعال کردن کوچک شدن R8 در برنامه ما، minifyEnabled را در فایل اصلی build.gradle روی true تنظیم کنید.
android {
…
buildTypes {
release {
minifyEnabled true
}
}
}
مقایسه R8 با Proguard
حالا بیایید R8 و Proguard را با هم مقایسه کنیم و ببینیم که چگونه کار می کند.
در Gradle بالاتر از 3.4.0 یا بیشتر، پروژه به طور پیش فرض از R8 استفاده می کند و دیگر از Proguard برای انجام بهینه سازی استفاده نمی کند. اما، فقط از قوانین Proguard استفاده می کند.
R8 ، کلاس های container را درون خط (inline) می کند و کلاس، فیلدها و متدهای استفاده نشده را حذف می کند. Proguard اندازه برنامه را 8.5٪ کاهش می دهد و در مقایسه با R8 که کد را 10٪ کاهش می دهد.
R8 در مقایسه با Proguard پشتیبانی بیشتری از Kotlin دارد.
R8 خروجی های بهتری نسبت به Proguard ارائه می دهد و این کار را سریعتر از Proguard انجام می دهد و در نتیجه build time را کاهش می دهد.
Proguard
هنگام استفاده از Proguard، کد برنامه ها توسط کامپایلر جاوا به bytecode جاوا تبدیل می شود. پس از تبدیل، توسط Proguard با استفاده از قوانینی که نوشته ایم بهینه سازی می شود. سپس dex آن را به Dalvik byte code بهینه شده تبدیل می کند.
این عمل تقریباً یک فرآیند 4 مرحله ای برای تبدیل آن به Dalvik byte code است.
R8
هنگام استفاده از R8، ابتدا کد برنامه توسط کامپایلر جاوا به bytecode جاوا تبدیل می شود و سپس با استفاده از R8 مستقیماً bytecode جاوا را به Dalvik byte code تبدیل می کند.
با استفاده از R8 مستقیماً مراحل تبدیل bytecode جاوا به Dalvik byte code را از 2 به 1 کاهش می دهد.
- Proguard ، 520 بهینه سازی peephole را در مقایسه با R8 اعمال می کند که بسیار کمتر است. بهینهسازیهای peephole بهینهسازیهایی هستند که روی مجموعهای از کدهای تولید شده توسط کامپایلر انجام میشوند تا با کوتاهتر و سریعتر کردن آن، عملکرد کد را بهبود ببخشند.
- در هر دو Proguard و R8، ما باید با نوشتن پیکربندی سفارشی، عکس العمل (reflection) را مدیریت کنیم.
- R8 در مقایسه با Proguard در اجرای تبدیل کد سریعتر است.
مقایسه بهینه سازی بین Proguard و R8
اجازه دهید در مورد چند ویژگی پشتیبانی شده توسط Proguard و R8 صحبت کنیم.
به عنوان مثال، Proguard و R8 هر دو ، متدها در کد را private می کنند. هر دوی آنها همچنین کلاس، فیلدها یا حتی متدهای استفاده نشده در پروژه را که استفاده نمی شوند حذف می کنند. هر دوی آنها از ساده سازی انواع Enum پشتیبانی می کنند. هر دو آنها متد درون خطی، کدهای ادغام و غیره پشتیبانی می کنند.
Proguard همچنین کلاس ها را final می کند در حالی که R8 قادر به انجام آن نیست. اما R8 ، به شدت توسط Kotlin پشتیبانی می شود، ساختار Kotlin را بهینه می کند که با Proguard امکان پذیر نیست.
حال، اگر می خواهید بهینه سازی تهاجمی (aggressive) را در R8 نیز فعال کنید و اندازه را بیشتر کاهش دهید، موارد زیر را در gradle.properties فعال کنید.
android.enableR8.fullMode=true
نتیجه گیری
با عرضه R8 به عنوان یک بهینه ساز پیش فرض زمان کامپایل، اندازه برنامه ، کاهش پیدا می کند.