R8 คือคอมไพเลอร์และเครื่องมือปรับแต่งโค้ด DEX ที่ทำการบีบอัด การลดรูป และการทำให้โค้ดสับสนของแอปพลิเคชัน Android ในขั้นตอนการ build ตามข้อมูลของ Google Android Performance Team (2025) การใช้ R8 ช่วยลดขนาด APK โดยเฉลี่ย 18% เมื่อเทียบกับ ProGuard และลดเวลา build ลง 30% ตั้งแต่ Android Gradle Plugin 8.0 เป็นต้นไป R8 ได้แทนที่ ProGuard อย่างสมบูรณ์ในฐานะเครื่องมือทำให้โค้ดสับสนมาตรฐาน
ประเด็นสำคัญ
R8 คือโปรแกรมประมวลผลและแปลงไบต์โค้ดที่พัฒนาโดย Google เพื่อแทนที่ ProGuard ในระบบนิเวศ Android แตกต่างจาก ProGuard ที่ทำงานเป็นเครื่องมือแยกต่างหากในขั้นตอนไฟล์ class R8 ถูกรวมเข้ากับคอมไพเลอร์ DEX (D8/R8) โดยตรง ซึ่งช่วยให้ R8 สามารถวิเคราะห์และปรับแต่งในระดับที่ลึกกว่า ซึ่งเครื่องมือ ภายนอก ไม่สามารถเข้าถึงได้
R8 รับไบต์โค้ด Java ในรูปแบบไฟล์ class หรือไฟล์เก็บถาวร JAR เป็นอินพุตและแปลงเป็นโค้ด DEX ที่ปรับแต่งแล้วในรอบเดียว ตัวปรับแต่งในตัวของ R8 ดำเนินการแปลงมากกว่า 50 ประเภท — ตั้งแต่แบบง่าย (การอินไลน์ค่าคงที่) ไปจนถึงซับซ้อน (การวิเคราะห์การเข้าถึงชนิดด้วยความแม่นยำระดับฟิลด์) ตามข้อมูลของ Google สถาปัตยกรรม R8 ถูกออกแบบมาโดยเฉพาะสำหรับการทำงานแบบมัลติเธรด ซึ่งรับประกันความเร็วในการ build สูง
R8 ถูกประกาศในงาน Google I/O 2018 และถูกรวมครั้งแรกใน Android Gradle Plugin 3.4 (2019) ในฐานะตัวเลือกแทน ProGuard ใน AGP 7.0 R8 กลายเป็นเครื่องมือเริ่มต้นสำหรับทุกโปรเจกต์ และใน AGP 8.0 (2023) การสนับสนุน ProGuard ถูกลบออกจากปลั๊กอินโดยสิ้นเชิง ณ ปี 2025 R8 เป็น เครื่องมือ อย่างเป็นทางการเดียวสำหรับการทำให้โค้ดสับสนและการปรับแต่งสำหรับ Android ที่ Google แนะนำ
R8 มอบความสามารถอันทรงพลังชุดหนึ่งให้กับนักพัฒนาที่เหนือกว่า ProGuard อย่างมีนัยสำคัญในด้านประสิทธิภาพ มาดูคุณสมบัติหลักกัน
R8 ดำเนินการวิเคราะห์ globally ของโค้ดแอปพลิเคชันและ dependencies ทั้งหมด โดยกำหนดคลาสและเมธอดที่เข้าถึงได้ผ่านกราฟการเรียกจากจุดเริ่มต้น การวิเคราะห์ของ R8 แม่นยำกว่า ProGuard เนื่องจากการเข้าถึงการแสดงโค้ดแบบ DEX R8 สามารถลบได้ไม่เพียงแค่คลาสและเมธอดทั้งหมด แต่ยังรวมถึงฟิลด์แต่ละรายการที่ไม่เคยถูกใช้งาน ตามการทดสอบของ Google R8 ลบ โค้ดมากกว่า 15% โดยเฉลี่ยเมื่อเทียบกับ ProGuard ในโปรเจกต์เดียวกัน
การลดรูปในตัวเป็นคุณสมบัติเฉพาะของ R8 ที่ไม่มีใน ProGuard R8 จะแปลงนิพจน์ lambda การอ้างอิงเมธอด อินเทอร์เฟซที่มีเมธอดเริ่มต้น และ try-with-resources ของ Java 8+ เป็นโค้ดที่เข้ากันได้ย้อนหลังที่ทำงานบนทุกระดับ API ของ Android โดยอัตโนมัติ ซึ่งช่วยลดความจำเป็นที่นักพัฒนาจะต้องเพิ่มไลบรารี desugar_jdk_libs แยกต่างหากและ กำหนดค่า การลดรูปด้วยตนเอง
เนื่องจาก R8 เห็นรูปแบบ DEX สุดท้าย มันจึงสามารถดำเนินการปรับแต่งที่เป็นไปไม่ได้สำหรับ ProGuard R8 รวมค่าคงที่สตริงที่เหมือนกัน ลบข้อยกเว้นที่ไม่ได้ใช้ ปรับแต่งโครงสร้าง switch และดำเนินการอินไลน์เชิงรุกพร้อมการเขียนกราฟการเรียกใหม่ การปรับแต่งเหล่านี้ไม่เพียงลดขนาด APK แต่ยัง ปรับปรุง ประสิทธิภาพการทำงานของโค้ดบน ART
// เปิดใช้งาน R8 อย่างชัดเจนใน build.gradle (ตัวเลือกใน AGP 8.0+)
android {
compileSdk 34
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'
), 'proguard-rules.pro'
}
}
}
// gradle.properties — บังคับเปิดใช้งาน R8
android.enableR8.fullMode=true
การเลือกระหว่าง R8 และ ProGuard มีความเกี่ยวข้องเฉพาะกับโปรเจกต์ที่ใช้ AGP ก่อนเวอร์ชัน 8.0 เพื่อทำความเข้าใจความแตกต่างทางสถาปัตยกรรม มาดูการเปรียบเทียบตามพารามิเตอร์หลักกัน
| พารามิเตอร์ | R8 | ProGuard |
|---|---|---|
| การรวม | รวมในคอมไพเลอร์ DEX | เครื่องมือแยกต่างหาก |
| การบีบอัดโค้ด | มีประสิทธิภาพมากกว่า 15% | ระดับพื้นฐาน |
| ความเร็วในการ build | เร็วขึ้น 20-30% | ความเร็วพื้นฐาน |
| การลดรูป | ในตัว | ไม่รองรับ |
| ความเข้ากันได้ของกฎ | เต็มรูปแบบกับ ProGuard | ไวยากรณ์มาตรฐาน |
| รองรับ AGP 8.0+ | ใช่ (มาตรฐาน) | ไม่ (ถูกลบ) |
การทดสอบของ Google กับตัวอย่างแอปยอดนิยม 100 รายการจาก Play Store แสดงให้เห็นว่า R8 ลดขนาด APK โดยเฉลี่ย 18% เมื่อเทียบกับ ProGuard ในบางโปรเจกต์ที่มีการใช้ไวยากรณ์ Java 8+ และไลบรารีของบริษัทอื่นอย่างหนัก ความแตกต่างถึง 28% สำหรับแอปพลิเคชันขนาด 40 MB นี่หมายถึงการประหยัด 5 ถึง 11 MB ซึ่งสำคัญสำหรับผู้ใช้ที่มีแบนด์วิดท์จำกัด
ทั้งสองเครื่องมือจัดการโค้ด Kotlin ได้อย่างถูกต้อง แต่ R8 ปรับแต่งโครงสร้างเฉพาะของ Kotlin ได้ดีกว่า: lambda ฟังก์ชัน inline โครูทีน และชนิดที่ปลอดภัย null R8 เข้าใจความหมายของเมทาดาทา Kotlin และสามารถลบการตรวจสอบ null ที่ไม่จำเป็นและฝังฟังก์ชัน inline ได้อย่างปลอดภัย สำหรับโปรเจกต์ Kotlin R8 เป็นเครื่องมือที่ Google แนะนำ
การตั้งค่า R8 ต้องการการเปลี่ยนแปลงเพียงเล็กน้อยในการกำหนดค่า build เนื่องจากใน AGP 8.0+ เครื่องมือนี้ถูกใช้เป็นค่าเริ่มต้น มาดูประเด็นสำคัญของการกำหนดค่ากัน
โหมดเต็มของ R8 (android.enableR8.fullMode=true) เปิดใช้งานการปรับแต่งเชิงรุกมากขึ้นซึ่งช่วยลดขนาด APK เพิ่มเติม 5-10% ในโหมดนี้ R8 จะวิเคราะห์โค้ดที่ลึกขึ้น โดยลบคลาสและเมธอดที่ ProGuard จะถือว่าสามารถเข้าถึงได้ โหมดเต็มอาจต้องใช้กฎ -keep เพิ่มเติมสำหรับไลบรารีที่ใช้ รีเฟลกชัน
# gradle.properties — เปิดใช้งานโหมดเต็มของ R8
android.enableR8.fullMode=true
# กฎเพิ่มเติมสำหรับโหมดเต็ม
-keep class com.example.reflection.** { *; }
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
เมื่อเกิดข้อผิดพลาดใน build แบบ release ด้วย R8 Google แนะนำ: ตรวจสอบไฟล์ mapping สำหรับการถอดรหัส stack trace ปิด fullMode ชั่วคราวเพื่อแยกปัญหา เพิ่ม -whyareyoukeeping เพื่อทำความเข้าใจว่าทำไมคลาสถึงไม่ถูกลบ และใช้แฟล็ก --info ของ Gradle เพื่อรับ บันทึก การประมวลผล R8 โดยละเอียด
เพื่อทำให้ build ด้วย R8 ใน CI/CD เป็นอัตโนมัติ การบันทึกไฟล์ mapping เป็นอาร์ติแฟกต์ของ build เป็นสิ่งสำคัญ ไฟล์ mapping แต่ละไฟล์ควรเชื่อมโยงกับหมายเลขเวอร์ชันและตัวแปร build Google แนะนำให้เก็บถาวร build/outputs/mapping/ พร้อมกับ APK/AAB ในระบบจัดการอาร์ติแฟกต์ ซึ่งจะรับประกันความสามารถในการ ถอดรหัส การขัดข้องจากทุกเวอร์ชันของแอปพลิเคชัน
ประสบการณ์หลายปีในการใช้ R8 ในชุมชน Android ได้สร้างชุดแนวทางปฏิบัติที่พิสูจน์แล้วซึ่งช่วยหลีกเลี่ยงปัญหาทั่วไปและได้รับประโยชน์สูงสุดจากเครื่องมือ
เมื่อย้ายจาก ProGuard ไปยัง R8 ขอแนะนำให้เริ่มต้นด้วย AGP 7.x ซึ่ง R8 เปิดใช้งานเป็นค่าเริ่มต้นแต่ fullMode ถูกปิดใช้งาน หลังจากตรวจสอบความเสถียรของ build บนชุดอุปกรณ์และสถานการณ์ที่ครบถ้วนแล้ว จึงสามารถเปิดใช้งาน fullMode ได้ แต่ละขั้นตอนต้องทดสอบ build แบบ release บน อุปกรณ์จริง ที่มี Android เวอร์ชันต่างๆ
ไฟล์ mapping ของ R8 มีรูปแบบเดียวกับ ProGuard แต่มีข้อมูลมากกว่าเนื่องจากการวิเคราะห์ที่ละเอียดยิ่งขึ้น Google แนะนำ: เก็บไฟล์ mapping ไว้อย่างไม่มีกำหนด — จำเป็นสำหรับการถอดรหัสการขัดข้องของเวอร์ชันเก่า รวมไฟล์ mapping กับ Firebase Crashlytics ผ่านการอัปโหลดอัตโนมัติ ตรวจสอบเป็นประจำว่าการถอดรหัสในคอนโซล Firebase กู้คืน ชื่อคลาสได้อย่างถูกต้อง
โหมดเต็มของ R8 อาจลบโค้ดที่ถือว่าสามารถเข้าถึงได้ในโหมดมาตรฐาน พื้นที่สำคัญสำหรับการทดสอบ: หน้าจอที่มี WebView (R8 อาจลบคลาสอินเทอร์เฟซ bridge) แอปพลิเคชันที่มีปลั๊กอินผ่าน classLoader ไลบรารีการวิเคราะห์และการรายงานการขัดข้อง และมุมมองที่กำหนดเองในไฟล์ layout ที่สร้างผ่าน inflate
Google แนะนำให้ติดตาม ขนาด APK หลังจากใช้ R8 ในทุก build ใช้ APK Analyzer ใน Android Studio เพื่อเปรียบเทียบขนาดของส่วนประกอบแต่ละส่วน: classes.dex, resources.arsc และไลบรารีโค้ดเนทีฟ R8 สามารถส่งผลต่อขนาดไฟล์ DEX แบบไม่เป็นเส้นตรง — บางครั้งการปรับแต่งเชิงรุกทำให้ขนาดเพิ่มขึ้นเนื่องจากการอินไลน์ การตรวจสอบเป็นประจำช่วยตรวจจับ ความผิดปกติ ได้ทันเวลาและปรับกฎการทำให้โค้ดสับสน
// ตัวอย่างคลาสที่เก็บไว้สำหรับ Firebase Crashlytics
@Keep
class CrashLogger {
fun logException(e: Throwable) {
FirebaseCrashlytics.getInstance().recordException(e)
}
}
// rules.pro — เก็บคลาสทั้งหมดที่มี @Keep
// -keep @androidx.annotation.Keep class * { *; }
คำถามที่พบบ่อย
ไม่ R8 ถูกรวมอยู่ใน Android Gradle Plugin และติดตั้งโดยอัตโนมัติเมื่อคุณอัปเดต AGP ตั้งแต่ AGP 8.0 เป็นต้นไป ProGuard ถูกลบออกจากปลั๊กอินโดยสมบูรณ์ และ R8 เป็นเครื่องมือเดียว สำหรับ AGP 7.x จะใช้ R8 เป็นค่าเริ่มต้น แต่ ProGuard ยังคงเป็นตัวเลือก ไม่จำเป็นต้องติดตั้ง R8 แยกต่างหาก — เพียง อัปเดต เวอร์ชัน AGP ของคุณ
R8 เร็วกว่าเนื่องจากสามปัจจัย: การรวมในคอมไพเลอร์ DEX ช่วยลดรอบการประมวลผลไบต์โค้ดเพิ่มเติม สถาปัตยกรรมแบบมัลติเธรดใช้โปรเซสเซอร์แบบมัลติคอร์ได้ดีขึ้น และการวิเคราะห์การเข้าถึงที่ชาญฉลาดยิ่งขึ้นช่วยลดปริมาณโค้ดที่ประมวลผล จากการทดสอบของ Google ในโปรเจกต์ขนาดกลาง R8 ดำเนินการประมวลผลเสร็จใน 12 วินาที เทียบกับ 18 วินาทีของ ProGuard
ใน AGP 7.x คุณสามารถปิด R8 ผ่าน gradle.properties: android.enableR8=false ใน AGP 8.0+ การกลับไปใช้ ProGuard เป็นไปไม่ได้เนื่องจากปลั๊กอินได้ย้ายไปใช้ R8 โดยสมบูรณ์แล้ว หากโปรเจกต์ต้องพึ่งพาพฤติกรรมเฉพาะของ ProGuard อย่างมาก ขอแนะนำให้锁定 AGP ที่เวอร์ชัน 7.4 ซึ่งมี เครื่องมือ ทั้งสองพร้อมใช้งาน
R8 จัดการโครูทีน Kotlin ได้อย่างถูกต้องเนื่องจากการวิเคราะห์เมทาดาทา Kotlin ในตัว เครื่องมือเข้าใจความหมายของฟังก์ชัน suspend ออบเจกต์ Continuation และการสร้าง StateMachine โดยคอมไพเลอร์ Kotlin R8 จะไม่ลบคลาสโครูทีนที่จำเป็นและสามารถปรับแต่งได้เมื่อปลอดภัย สำหรับโปรเจกต์ Kotlin ขอแนะนำ โหมดเต็ม เพื่อการปรับแต่งสูงสุด
ปัญหา ที่พบบ่อยที่สุดระหว่างการย้าย: คลาสหายไป — R8 ลบคลาสที่ ProGuard เก็บไว้ ปัญหาการอินไลน์ — การอินไลน์เชิงรุกทำให้รีเฟลกชันเสีย ความไม่เข้ากันของไลบรารี — ไลบรารีที่มีกฎ ProGuard เก่า โหมดเต็มขัดข้อง — การลบโค้ดเพิ่มเติมใน fullMode วิธีแก้ไข: ทดสอบบนอุปกรณ์จริง ใช้ -keep สำหรับรีเฟลกชันและ ตรวจสอบ stack trace ผ่านไฟล์ mapping
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม