กรณีศึกษา

Grab ลด ANR ได้ 32% และปรับปรุงเวลาเริ่มต้นได้ 35% ด้วย R8 และการเพิ่มประสิทธิภาพที่กำหนดโดยโปรไฟล์

ใช้เวลาอ่าน 5 นาที
3 ผู้เขียน
Ajesh Pai, Nguyen Van Minh, Tracy Agyemang

Grab เป็นซูเปอร์แอปชั้นนำของเอเชียตะวันออกเฉียงใต้ที่ให้บริการจัดส่ง การเดินทาง และบริการทางการเงินแก่ผู้ใช้หลายล้านคนใน 8 ประเทศผ่านแอปเดียว ด้วยฐานของโค้ดที่มีอายุ 10 ปีซึ่งมีโค้ดมากกว่า 10 ล้านบรรทัดและไลบรารีของบุคคลที่สามหลายร้อยรายการที่สร้างขึ้นโดยใช้การตั้งค่า Bazel และ Gradle แบบผสม ทีม Grab ต้องเผชิญกับความท้าทายที่เพิ่มขึ้น 3 ประการ ได้แก่ อัตราแอปพลิเคชันไม่ตอบสนอง (ANR) ที่สูง ขนาดแอปที่เพิ่มขึ้นเรื่อยๆ เมื่อซูเปอร์แอปเพิ่มบริการใหม่ๆ และเวลาเริ่มต้นที่ค่อยๆ เพิ่มขึ้นเมื่อเทียบกับปีก่อน  การเปิดใช้การเพิ่มประสิทธิภาพ R8, การปรับแต่งกฎการเก็บรักษา และการใช้โปรไฟล์พื้นฐานและโปรไฟล์การเริ่มต้นระบบช่วยให้ Grab ลดอัตรา ANR ที่ผู้ใช้รับรู้ได้ 32%, ลดขนาดการดาวน์โหลดแอปลงประมาณ 30% และปรับปรุงเวลาเริ่มต้นระบบได้ 35%

การกำจัดปัญหา ANR ที่เพิ่มขึ้นอย่างรวดเร็วหลังการเผยแพร่เพื่อประสบการณ์ของผู้ใช้ที่ราบรื่นยิ่งขึ้น

ก่อนที่จะเพิ่มประสิทธิภาพกระบวนการบิลด์ Grab ประสบปัญหาความล่าช้าในการเริ่มทำงานแบบ Cold Start และข้อผิดพลาดแอปไม่ตอบสนอง (ANR) ที่เพิ่มขึ้นอย่างรวดเร็วทันทีหลังจากการอัปเดตใหม่ๆ ซึ่งส่วนใหญ่เกิดจากค่าใช้จ่ายเพิ่มเติมในการอ่านไฟล์ DEX จำนวนมากระหว่างการเริ่มต้นแอป 

แม้ว่าโปรไฟล์ระบบคลาวด์ของ Google Play จะช่วยเพิ่มประสิทธิภาพให้กับขั้นตอนมาตรฐานในฐานผู้ใช้โดยรวม แต่ก็ไม่ได้เพิ่มประสิทธิภาพเส้นทางการเริ่มต้นทั้งหมดที่จำเป็นสำหรับเส้นทางของผู้ใช้ที่สำคัญของ Grab เช่น การเริ่มต้นกราฟทรัพยากร Dependency ของ Dagger ระหว่างการเปิดแอป สำหรับเส้นทางโค้ดที่ไม่ได้ครอบคลุมในการกระจายครั้งแรก อุปกรณ์จะอาศัยการคอมไพล์ JIT และการเพิ่มประสิทธิภาพในเบื้องหลังของอุปกรณ์ในวันต่อๆ มา การใช้ Baseline Profile ที่กำหนดเองช่วยแก้ปัญหานี้ได้โดยการระบุเส้นทางของผู้ใช้ที่สำคัญเหล่านี้ลงใน Cloud Profile ของ Google Play โดยตรง ซึ่งจะขยายขอบเขตการเพิ่มประสิทธิภาพเพื่อให้เส้นทางหลักเหล่านี้ได้รับการคอมไพล์เป็นรหัสเครื่องทันทีที่ติดตั้ง 

ANDDM_Grab_Inline_Quote_ALT.png

"เราพบว่าอัตรา ANR เพิ่มขึ้นอย่างต่อเนื่องทุกครั้งที่เปิดตัวแอปรายสัปดาห์" Nguyen Van Minh หัวหน้าวิศวกรซอฟต์แวร์ในทีม Passenger App Core ของ Grab อธิบาย 

Grab ได้ใช้การเพิ่มประสิทธิภาพ R8, โปรไฟล์พื้นฐาน และโปรไฟล์การเริ่มต้นระบบเพื่อกำจัด ANR และปรับปรุงเวลาเริ่มต้นระบบ การเพิ่มประสิทธิภาพที่อิงตามโปรไฟล์ควบคู่ไปกับเครื่องมือเพิ่มประสิทธิภาพ R8 ช่วยปรับปรุง Cold Start ได้ทันที 12% จาก R8 และอีก 15% จากโปรไฟล์พื้นฐาน ซึ่งทำให้เวลาเริ่มต้นเร็วขึ้น 27% และกำจัด ANR ที่เพิ่มขึ้นอย่างรวดเร็วหลังการเผยแพร่ได้อย่างมีประสิทธิภาพ

Grab ดำเนินการเพิ่มประสิทธิภาพแอปนี้ใน 3 ระยะเชิงกลยุทธ์ ได้แก่ การเปิดใช้การเพิ่มประสิทธิภาพ R8 ในโหมดความเข้ากันได้ การเปลี่ยนไปใช้โหมดเต็มรูปแบบของ R8 จากนั้นปรับแต่งกฎการเก็บรักษาด้วยเครื่องมือวิเคราะห์การกำหนดค่า และเพิ่มการกำกับดูแล CI/CD

ระยะที่ 1: การเปิดใช้การเพิ่มประสิทธิภาพ R8  (เปิดตัวในปี 2025)

ในระยะแรกนี้ Grab ได้เปลี่ยนจากการใช้ไฟล์ Proguard เริ่มต้นแบบเดิมมาใช้ proguard-android-optimize.txt ซึ่งเปิดใช้การเพิ่มประสิทธิภาพ R8  เนื่องจากฐานของโค้ดมีอายุมากกว่า 10 ปีและมีโค้ดมากกว่า 10 ล้านบรรทัด การเปิดใช้เครื่องมือเพิ่มประสิทธิภาพจึงต้องจัดการกับการกำหนดค่าเดิมและการใช้การสะท้อน

Grab ได้เปิดตัวการอัปเดตแอปที่เปิดใช้โหมดความเข้ากันได้ของ R8 พร้อมโปรไฟล์พื้นฐานและโปรไฟล์การเริ่มต้นระบบเพื่อเพิ่มผลลัพธ์ของระยะนี้ให้ได้สูงสุด ความพยายามร่วมกันนี้ส่งผลให้อัตรา ANR ที่ผู้ใช้รับรู้ลดลง 25% ในทันที ขนาดการดาวน์โหลดแอปลดลง 16% และเวลาเริ่มต้นแบบ Cold Start โดยรวมดีขึ้น 27%

ระยะที่ 2: โหมดเต็มและการย้ายข้อมูล R8 (เปิดตัวในปี 2026)

ระยะนี้เปิดตัวหลังจากเปิดตัวครั้งแรก 9 เดือน โดยเปลี่ยนแอปเป็นโหมดเต็มรูปแบบ R8 ซึ่งช่วยให้เพิ่มประสิทธิภาพได้มากขึ้น แม้ว่าไลบรารีมาตรฐานอย่าง Retrofit, Firebase และ Jetpack Compose จะทำงานร่วมกับ R8 ได้อย่างราบรื่นโดยใช้กฎในตัว แต่การย้ายข้อมูลฐานของโค้ดขนาดใหญ่ที่เหลือก็ทำได้โดยการแก้ไขเส้นทางโค้ดที่ใช้การสะท้อนอย่างหนักหน่วงโดยเฉพาะ ดังนี้

ในการย้ายข้อมูลไปยังโหมด R8 แบบเต็ม ทีมได้นำกฎการเก็บรักษาของผู้ใช้จาก Gson เวอร์ชันล่าสุดมาใช้เพื่อให้แยกวิเคราะห์ JSON ได้อย่างราบรื่น นอกจากนี้ ยังได้แก้ไขปัญหาด้านการเพิ่มประสิทธิภาพด้วยพร็อกซีแบบไดนามิกของ Java ซึ่งใช้การสะท้อนเพื่อสร้างการติดตั้งใช้งานอินเทอร์เฟซที่รันไทม์ เนื่องจาก R8 ไม่สามารถตรวจจับการใช้งานรันไทม์นี้ระหว่างการคอมไพล์ จึงตัดหรือเปลี่ยนชื่อคลาสที่จำเป็น ซึ่งทำให้แอปพลิเคชันขัดข้อง ทีมจึงแยกคลาสที่เฉพาะเจาะจงซึ่งอาศัยการสะท้อนและใช้กฎการเก็บรักษาที่มีการกำหนดเป้าหมายสูง แทนที่จะใช้ข้อยกเว้นแบบกว้างๆ ซึ่งจะทำให้ขนาดแอปเพิ่มขึ้น ซึ่งช่วยรักษาทั้งความเสถียรของแอปและประสิทธิภาพในการเพิ่มประสิทธิภาพ

ท้ายที่สุดแล้ว โหมดเต็มรูปแบบของ R8 ช่วยปรับปรุงประสิทธิภาพแบบทวีคูณอย่างมหาศาล ซึ่งรวมถึงการลดขนาดการดาวน์โหลดแอปลงอีก 14% เวลาเริ่มต้นทำงานดีขึ้นอีก 10% และ ANR ที่ผู้ใช้รับรู้ลดลงอีก 10% หลังจากย้ายข้อมูลไปยังโหมดเต็มรูปแบบของ R8 ฐานของโค้ดของ Grab ได้รับคะแนนการเพิ่มประสิทธิภาพ R8 ดังนี้ 

  • คะแนนการเพิ่มประสิทธิภาพ: 72%
  • คะแนนการลดขนาด: 73%
  • คะแนนการปรับให้ยากต่อการอ่าน (Obfuscation): 79.6%

คะแนนเหล่านี้ให้ความคิดเห็นเกี่ยวกับการกำหนดค่า R8 และความจำเป็นในการปรับแต่งกฎการเก็บรักษาเพื่อเพิ่มประสิทธิภาพ R8 ให้สูงสุด 

ระยะที่ 3: การปรับแต่งกฎการเก็บรักษา 

ในระยะสุดท้ายของเส้นทางการเพิ่มประสิทธิภาพ Grab มุ่งเน้นที่การสร้างประสิทธิภาพของฐานของโค้ดในระยะยาว การตรวจสอบประสิทธิภาพอย่างต่อเนื่อง และการกำกับดูแลการคอมไพล์ที่เข้มงวด ทีมกำลังผสานรวมเครื่องมือวิเคราะห์การกำหนดค่า R8 เข้ากับเวิร์กโฟลว์การประเมินเพื่อวัดความถูกต้องของกฎอย่างเป็นระบบและป้องกันการถดถอยของการกำหนดค่าในรอบการเผยแพร่ที่ดำเนินอยู่ เครื่องมือนี้ช่วยให้เห็นภาพอย่างละเอียดว่ากฎการเก็บของ Grab ช่วยให้ R8 เพิ่มประสิทธิภาพ ย่อขนาด และสร้างความสับสนให้กับแอปพลิเคชันได้อย่างมีประสิทธิภาพเพียงใด

การต่อยอดจากรากฐานของโหมดเต็มรูปแบบ R8 และการตัดกฎการเก็บรักษาเดิมออกอย่างเป็นระบบช่วยให้ Grab ปรับปรุงประสิทธิภาพได้อย่างมากในมิติข้อมูลหลักทั้ง 3 รายการที่เครื่องมือวิเคราะห์ประเมิน ดังนี้

  • คะแนนการเพิ่มประสิทธิภาพ: เพิ่มขึ้นจาก 72% เป็น 78.2%
  • คะแนนการลดขนาด: เพิ่มขึ้นจาก 73% เป็น 79.1%
  • คะแนนการปรับให้ยากต่อการอ่าน (Obfuscation): เพิ่มขึ้นจาก 79.6% เป็น 81.7%

นอกเหนือจากการเพิ่มคะแนนการวินิจฉัยเหล่านี้แล้ว ขั้นตอนการปรับแต่งกฎการเก็บรักษาโดยเฉพาะนี้ยังช่วยลดขนาดการดาวน์โหลดแอปลงได้อีกประมาณ 3.6% ที่สำคัญกว่านั้น การติดตามเมตริกเหล่านี้ช่วยให้ทีมวิศวกรได้รับข้อมูลเชิงวัตถุที่จำเป็นต่อการใช้ Guardrail ของ CI แบบรวมล่วงหน้าอัตโนมัติ เพื่อให้มั่นใจว่าโค้ดที่เปิดตัวใหม่เป็นไปตามมาตรฐาน Keep-Rule ที่เข้มงวด และประสิทธิภาพที่เพิ่มขึ้นอย่างยากลำบากจะยังคงได้รับการปกป้องเมื่อเวลาผ่านไป

ผลลัพธ์

การปรับปรุงประสิทธิภาพที่สำคัญหลังจากการเปิดตัวเครื่องมือเพิ่มประสิทธิภาพ R8 มีดังนี้

ระยะการเพิ่มประสิทธิภาพANRขนาดCold Start
ระยะที่ 1: เครื่องมือเพิ่มประสิทธิภาพ R8 (เปิดตัวในปี 2025)ลดลง ~25%ลดลง 16%ปรับปรุงขึ้นประมาณ 27%
ระยะที่ 2: โหมดเต็มรูปแบบของ R8 (เปิดตัวในปี 2026)ลดลง 10%ลดลง 14%ปรับปรุง 10%
การเพิ่มประสิทธิภาพกฎการเก็บรักษา-ลดลง 3.6%-
ภาพรวม (สะสม)ลดลง ~32.5%ลดลง ~30.4%ปรับปรุงได้ประมาณ 35%

อุปสรรคทางเทคนิค 

การเปิดใช้เครื่องมือเพิ่มประสิทธิภาพ R8 ในฐานของโค้ดที่มีอายุ 10 ปีของ Grab ทำให้เกิดอุปสรรคทางเทคนิคที่สำคัญในวงกว้าง ดังนี้

  • การทดสอบ: การสะท้อนแสงที่สะสมมานานนับทศวรรษทำให้เกิดกรณีสุดโต่งภายใต้การเพิ่มประสิทธิภาพอย่างเต็มรูปแบบ เนื่องจากการทดสอบอย่างละเอียดใน LOC หลายล้านรายการเป็นไปไม่ได้ ทีมจึงใช้แนวทางแบบค่อยเป็นค่อยไปและให้ความสำคัญสูง โดยมุ่งเน้นการทดสอบการครอบคลุมของโค้ดที่ครอบคลุมโดยกฎการเก็บรักษาที่แคบลง และปรับแต่งกฎเหล่านั้นซ้ำๆ เพื่อกำหนดเป้าหมายเฉพาะคลาส เมธอด หรือฟิลด์ที่จำเป็นสำหรับการสะท้อนเพื่อเพิ่มประสิทธิภาพ R8 ให้สูงสุด
  • เวลาในการตอบสนองของบิลด์และสถาปัตยกรรมแบบผสม: ระบบบิลด์แบบผสมของ Grab (Bazel สำหรับการแก้ไขข้อบกพร่อง, Gradle สำหรับบิลด์ที่เผยแพร่ R8) หมายความว่าการเปลี่ยนแปลง R8 เวอร์ชันทดลองใช้เวลาถึง 2 ชั่วโมงใน CI ระยะไกล เพื่อลดช่องว่างของความคิดเห็น Grab ได้ปรับ QA Build รายวันให้สอดคล้องกับลักษณะการทำงานของ R8 เวอร์ชันที่ใช้งานจริง และทำให้การรวบรวมอาร์ติแฟกต์บิลด์ CI ที่สำคัญ เช่น mapping.txt, configuration.txt เป็นแบบอัตโนมัติเพื่อการตรวจสอบที่มีประสิทธิภาพ
  • วงจรการแก้ไขข้อบกพร่องที่ช้า: การติดตามสาเหตุของปัญหาในคลาสที่เพิ่มประสิทธิภาพหลายร้อยคลาสสร้างภาระหนักให้กับทีมที่มีขนาดเล็ก Grab แก้ไขปัญหานี้ด้วยการอัปโหลดไฟล์การแมปไปยัง Firebase Crashlytics โดยอัตโนมัติผ่าน Gradle และรวมการแมปการถอดรหัสซอร์สโค้ดที่สร้างความสับสนสำหรับ Play Console ซึ่งช่วยให้แก้ไขสัญลักษณ์สำหรับปัญหาเกี่ยวกับรันไทม์ได้อย่างรวดเร็วและแม่นยำ

ผลกระทบระยะยาวของโค้ดที่มีต่อ R8

นอกเหนือจากประสิทธิภาพที่เพิ่มขึ้นในทันทีแล้ว การเปิดใช้เครื่องมือเพิ่มประสิทธิภาพ R8 ยังช่วยให้ฐานของโค้ดขนาดใหญ่ของ Grab มีข้อได้เปรียบด้านโครงสร้างอย่างถาวรด้วย ทีมของ Grab ใช้เครื่องมือโอเพนซอร์ส app-sizer เพื่อวัดผลของ R8 และพบว่า R8 ช่วยลดขนาดการดาวน์โหลดของโค้ดทุกบรรทัดในแอปได้อย่างถาวร

ANDDM_Grab_Inline_Metric.png

ในยุคของการพัฒนาที่มีการใช้งาน AI ซึ่งปริมาณโค้ดเพิ่มขึ้นอย่างรวดเร็ว การเพิ่มประสิทธิภาพนี้จึงมีความสำคัญมากยิ่งขึ้น หากไม่มี R8 การขยายโค้ดจะเพิ่มขนาดการดาวน์โหลดตามสัดส่วน R8 ช่วยให้มั่นใจได้ว่าอัตราการขยายโค้ดที่เท่ากันจะช่วยลดหน่วยความจำที่ใช้ได้อย่างมาก

หมายเหตุ: วิธีการ: การมีส่วนร่วมของ Kotlin/Java ของ app-sizer ต่อขนาดการดาวน์โหลดแอป (อุปกรณ์ตัวแทน) หารด้วย Kotlin LOC เวอร์ชันที่ใช้งานจริง (cloc; ชุดซอร์สหลักเท่านั้น; ไม่รวมโมดูลทดสอบ, โมดูลจำลอง และโมดูลตัวอย่าง)

การจัดการกฎและมาตรการป้องกันของ Keep

เพื่อป้องกันไม่ให้กฎเสื่อมประสิทธิภาพและคงการเพิ่มประสิทธิภาพ R8 ไว้เมื่อเวลาผ่านไป Grab วางแผนที่จะผสานรวม Guardrail ก่อนการผสานแบบอัตโนมัติลงในไปป์ไลน์ CI โดยตรง ภายใต้นโยบายนี้ กฎการเก็บรักษาใหม่จะถูกจำกัดอย่างเข้มงวด โดยกฎเพิ่มเติมใดๆ จะต้องมีเหตุผลประกอบและการตรวจสอบที่ชัดเจน ทีมที่ Grab ติดตามคะแนนการเพิ่มประสิทธิภาพ R8 ใน CI ทีมวางแผนที่จะใช้เมตริกเหล่านี้เป็นรายงานความคิดเห็นอย่างต่อเนื่อง เพื่อให้ตรวจพบการถดถอยก่อนการผสานรวมและคงประสิทธิภาพที่เพิ่มขึ้นไว้ในทุกรอบการเผยแพร่ 

R8-rules-score (1).png

รูปที่ 1: แดชบอร์ด CI ที่ติดตามคะแนนการลดขนาด การเพิ่มประสิทธิภาพ และการสร้างความสับสนของ R8 เมื่อเวลาผ่านไปในบิลด์ของ Grab เพื่อตรวจหาและป้องกันการถดถอยในรุ่นต่างๆ ในเชิงรุก

สรุป 

เมื่อต้องเผชิญกับความท้าทายของฐานของโค้ดขนาดใหญ่ที่เติบโตเต็มที่ ทีม Pax App Core ของ Grab ได้จัดการกับเวลาเริ่มต้นที่เพิ่มขึ้นและประสิทธิภาพที่พุ่งสูงขึ้นหลังการเปิดตัวอย่างเชิงรุกด้วยการใช้โปรไฟล์พื้นฐานและปรับปรุงการกำหนดค่า R8 อย่างต่อเนื่อง ทีมลด ANR ที่ผู้ใช้รับรู้ได้ประมาณ 32.5% ลดขนาดการดาวน์โหลดแอปลงประมาณ 30.3% และปรับปรุงเวลา Cold Start ได้ประมาณ 35% พร้อมทั้งปรับปรุงประสิทธิภาพการปรับขนาดฐานของโค้ดโดยพื้นฐาน

การเพิ่มประสิทธิภาพเหล่านี้ช่วยให้ผู้ใช้หลายล้านคนทั่วเอเชียตะวันออกเฉียงใต้ได้รับประสบการณ์การใช้งานซูเปอร์แอปที่รวดเร็วและเสถียรยิ่งขึ้น ขณะเดียวกันก็ช่วยให้วิศวกรของ Grab มีเครื่องมือในการสร้างฟีเจอร์ได้เร็วขึ้นโดยไม่ต้องกังวลเรื่องขนาดการดาวน์โหลดที่เพิ่มขึ้นอย่างรวดเร็ว

หากต้องการเริ่มต้นใช้งานและดูข้อมูลเพิ่มเติมเกี่ยวกับ R8 โปรดไปที่ - d.android.com/r8

เขียนโดย
อ่านต่อ