เปรียบเทียบเมตริก "เขียน" และ "ดู"

Jetpack Compose ช่วยเร่งการพัฒนา UI และปรับปรุงการพัฒนา Android อย่างไรก็ตาม โปรดพิจารณาว่าการเพิ่ม Compose ลงในแอปที่มีอยู่จะส่งผลต่อเมตริกต่างๆ เช่น ขนาด APK ของแอป ประสิทธิภาพของบิลด์และรันไทม์อย่างไร

ขนาด APK และเวลาในการบิลด์

ส่วนนี้จะอธิบายผลกระทบต่อขนาด APK และเวลาในการสร้างโดยดูที่แอปตัวอย่าง Sunflower ซึ่งเป็นแอปที่สาธิตแนวทางปฏิบัติแนะนำในการย้ายข้อมูลแอปที่อิงตาม View ไปยัง Compose

ขนาด APK

การเพิ่มไลบรารีลงในโปรเจ็กต์จะเพิ่มขนาด APK ผลลัพธ์ต่อไปนี้เป็นของ APK รุ่นที่ลดขนาดแล้วของแต่ละโปรเจ็กต์ซึ่งเปิดใช้การลดขนาดทรัพยากรและโค้ด โดยใช้โหมดเต็มรูปแบบของ R8 และวัดโดยใช้ตัววิเคราะห์ APK

ดูอย่างเดียว มุมมองแบบผสมและ Compose เขียนเท่านั้น
ขนาดการดาวน์โหลด 2,252 KB 3,034 KB 2,966 KB

เมื่อเพิ่ม Compose ลงใน Sunflower เป็นครั้งแรก ขนาด APK เพิ่มขึ้นจาก 2,252 KB เป็น 3,034 KB ซึ่งเพิ่มขึ้น 782 KB APK ที่สร้างขึ้นประกอบด้วย UI ที่สร้างขึ้นด้วย View และ Compose ผสมกัน การเพิ่มขึ้นนี้เป็นสิ่งที่คาดไว้เนื่องจากมีการเพิ่มทรัพยากร Dependency เพิ่มเติมลงใน Sunflower

ในทางกลับกัน เมื่อย้ายข้อมูล Sunflower ไปยังแอปที่ใช้ Compose อย่างเดียว ขนาด APK ลดลงจาก 3,034 KB เป็น 2,966 KB ซึ่งลดลง 68 KB การลดลงนี้เกิดจากการนำทรัพยากร Dependency ของ View ที่ไม่ได้ใช้ออก เช่น AppCompat และ ConstraintLayout

เวลาที่บิวด์ใช้

การเพิ่ม Compose จะเพิ่มเวลาบิลด์ของแอปเนื่องจากคอมไพเลอร์ Compose จะประมวลผล Composable ในแอป ผลลัพธ์ต่อไปนี้ได้มาจากการใช้เครื่องมือ gradle-profiler แบบสแตนด์อโลน ซึ่งจะสร้างบิลด์หลายครั้งเพื่อให้ได้เวลาบิลด์เฉลี่ยสำหรับระยะเวลาบิลด์การแก้ไขข้อบกพร่องของ Sunflower

gradle-profiler --benchmark --project-dir . :app:assembleDebug
ดูอย่างเดียว มุมมองแบบผสมและ Compose เขียนเท่านั้น
เวลาสร้างเฉลี่ย 299.47 มิลลิวินาที 399.09 มิลลิวินาที 342.16 มิลลิวินาที

เมื่อเพิ่ม Compose ลงใน Sunflower เป็นครั้งแรก เวลาในการสร้างเฉลี่ยเพิ่มขึ้นจาก 299 มิลลิวินาทีเป็น 399 มิลลิวินาที ซึ่งเพิ่มขึ้น 100 มิลลิวินาที ระยะเวลานี้เกิดจากคอมไพเลอร์ Compose ทำงานเพิ่มเติมเพื่อเปลี่ยนรูปแบบโค้ด Compose ที่กำหนดไว้ในโปรเจ็กต์

ในทางกลับกัน เวลาในการบิลด์เฉลี่ยลดลงเหลือ 342 มิลลิวินาที ซึ่งลดลง 57 มิลลิวินาทีเมื่อการย้ายข้อมูลของ Sunflower ไปยัง Compose เสร็จสมบูรณ์ การลดเวลานี้เกิดจากปัจจัยหลายอย่างที่ช่วยลดเวลาในการบิลด์ เช่น การนำการเชื่อมโยงข้อมูลออก การย้ายข้อมูลทรัพยากร Dependency ที่ใช้ kapt ไปยัง KSP และการอัปเดตทรัพยากร Dependency หลายรายการเป็นเวอร์ชันล่าสุด

สรุป

การใช้ Compose จะเพิ่มขนาด APK ของแอปอย่างมีประสิทธิภาพ และยังเพิ่มประสิทธิภาพเวลาในการสร้างแอปเนื่องจากกระบวนการคอมไพล์โค้ด Compose ด้วย อย่างไรก็ตาม ข้อดีข้อเสียเหล่านี้ต้องได้รับการพิจารณาเทียบกับประโยชน์ของ Compose โดยเฉพาะอย่างยิ่งในเรื่องประสิทธิภาพการทำงานของนักพัฒนาซอฟต์แวร์ที่เพิ่มขึ้นเมื่อใช้ Compose ตัวอย่างเช่น ทีม Play Store พบว่าการเขียน UI ต้องใช้โค้ดน้อยลงมาก บางครั้งลดลงถึง 50% ซึ่งช่วยเพิ่มประสิทธิภาพการทำงานและความสามารถในการบำรุงรักษาโค้ด

อ่านกรณีศึกษาเพิ่มเติมได้ในการนำ Compose ไปใช้สำหรับทีม

ประสิทธิภาพของรันไทม์

ส่วนนี้ครอบคลุมหัวข้อที่เกี่ยวข้องกับประสิทธิภาพรันไทม์ใน Jetpack Compose เพื่อช่วยให้เข้าใจว่า Jetpack Compose มีประสิทธิภาพอย่างไรเมื่อเทียบกับระบบ View และวิธีวัดประสิทธิภาพดังกล่าว

การจัดองค์ประกอบอัจฉริยะ

เมื่อบางส่วนของ UI ไม่ถูกต้อง Compose จะพยายามจัดองค์ประกอบใหม่เฉพาะส่วนที่ต้องอัปเดต อ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ในเอกสารประกอบเรื่องวงจรของ Composable และระยะต่างๆ ของ Jetpack Compose

โปรไฟล์พื้นฐาน

โปรไฟล์พื้นฐานเป็นวิธีที่ยอดเยี่ยมในการเร่งเส้นทางของผู้ใช้ทั่วไป การรวม Baseline Profile ไว้ในแอปจะช่วยเพิ่มความเร็วในการเรียกใช้โค้ดได้ประมาณ 30% จากการเปิดใช้งานครั้งแรก โดยหลีกเลี่ยงขั้นตอนการตีความและการคอมไพล์ JIT สำหรับเส้นทางโค้ดที่รวมไว้

ไลบรารี Jetpack Compose มี Baseline Profile ของตัวเอง และคุณจะได้รับการเพิ่มประสิทธิภาพเหล่านี้โดยอัตโนมัติเมื่อใช้ Compose ในแอป อย่างไรก็ตาม การเพิ่มประสิทธิภาพเหล่านี้จะส่งผลต่อเส้นทางโค้ดภายในไลบรารี Compose เท่านั้น เราจึงขอแนะนำให้คุณเพิ่ม Baseline Profile ลงในแอปเพื่อให้ครอบคลุมเส้นทางโค้ดนอก Compose

การเปรียบเทียบกับระบบ View

Jetpack Compose มีการปรับปรุงหลายอย่างเมื่อเทียบกับระบบ View เราจะอธิบายการปรับปรุงเหล่านี้ในส่วนต่อไปนี้

ทุกอย่างจะขยาย View

View ทุกรายการที่วาดบนหน้าจอ เช่น TextView, Button หรือ ImageView ต้องมีการจัดสรรหน่วยความจำ การติดตามสถานะที่ชัดเจน และ Callback ต่างๆ เพื่อรองรับ Use Case ทั้งหมด นอกจากนี้ เจ้าของ View ที่กำหนดเองต้องใช้ตรรกะที่ชัดเจนเพื่อป้องกันการวาดใหม่เมื่อไม่จำเป็น เช่น สำหรับการประมวลผลข้อมูลซ้ำๆ

Jetpack Compose แก้ไขปัญหานี้ได้หลายวิธี Compose ไม่มีออบเจ็กต์ที่อัปเดตได้ชัดเจนสำหรับการวาดมุมมอง องค์ประกอบ UI เป็นฟังก์ชันที่ประกอบกันได้แบบง่ายๆ ซึ่งมีการเขียนข้อมูลลงใน Composition ในลักษณะที่เล่นซ้ำได้ ซึ่งจะช่วยลดการติดตามสถานะที่ชัดเจน การจัดสรรหน่วยความจำ และ Callback ให้เหลือเฉพาะ Composable ที่ต้องใช้ฟีเจอร์ดังกล่าว แทนที่จะกำหนดให้ส่วนขยายทั้งหมดของประเภท View ที่ระบุต้องใช้ฟีเจอร์นี้

นอกจากนี้ Compose ยังมีการจัดองค์ประกอบใหม่อัจฉริยะ ซึ่งจะเล่นผลลัพธ์ที่วาดไว้ก่อนหน้านี้ซ้ำหากคุณไม่จำเป็นต้องทำการเปลี่ยนแปลง

การส่งผ่านเลย์เอาต์หลายรายการ

ViewGroup แบบดั้งเดิมมีความสามารถในการแสดงออกอย่างมากใน API การวัดค่าและเลย์เอาต์ ซึ่งทำให้มีแนวโน้มที่จะเกิดการส่งผ่านเลย์เอาต์หลายครั้ง การส่งผ่านเลย์เอาต์หลายรายการเหล่านี้อาจทำให้งานเพิ่มขึ้นแบบทวีคูณหากทำที่จุดที่ฝังเฉพาะในลำดับชั้นการแสดงผล

Jetpack Compose บังคับใช้การส่งผ่านเลย์เอาต์เดียวสำหรับ Composable ของเลย์เอาต์ทั้งหมดผ่านสัญญา API ซึ่งช่วยให้ Compose จัดการแผนผัง UI ที่ซับซ้อนได้อย่างมีประสิทธิภาพ หากจำเป็นต้องวัดหลายครั้ง Compose จะมีการวัดค่าภายใน

ดูประสิทธิภาพการเริ่มต้นระบบ

ระบบ View ต้องขยายเลย์เอาต์ XML เมื่อแสดงเลย์เอาต์หนึ่งๆ เป็นครั้งแรก Jetpack Compose ช่วยประหยัดต้นทุนนี้เนื่องจากเลย์เอาต์เขียนด้วย Kotlin และคอมไพล์เหมือนกับส่วนอื่นๆ ของแอป

เปรียบเทียบ Compose

ใน Jetpack Compose ประสิทธิภาพของแอปในโหมด debug และ release มีความแตกต่างกันอย่างเห็นได้ชัด หากต้องการเวลาที่เป็นตัวแทน ให้ใช้บิลด์ release แทน debug เสมอเมื่อสร้างโปรไฟล์แอป

หากต้องการตรวจสอบประสิทธิภาพของโค้ด Jetpack Compose คุณสามารถใช้ไลบรารี Jetpack Macrobenchmark ดูวิธีใช้กับ Jetpack Compose ได้ที่โปรเจ็กต์ MacrobenchmarkSample

ทีม Jetpack Compose ยังใช้ Macrobenchmark เพื่อติดตามการถดถอยและตรวจสอบประสิทธิภาพเทียบกับ Views ในรุ่นต่างๆ ด้วย ดูการเปรียบเทียบประสิทธิภาพการเริ่มต้นและการเลื่อนโดยละเอียดระหว่าง Compose กับ Views ในแอป Pokedex แบบโอเพนซอร์สได้ที่การเปรียบเทียบประสิทธิภาพหลัก

การติดตั้งโปรไฟล์ Compose

เนื่องจาก Jetpack Compose เป็นไลบรารีที่แยกต่างหาก จึงไม่ได้รับประโยชน์จาก Zygote ที่โหลดคลาส UI Toolkit และ Drawable ของระบบ View ไว้ล่วงหน้า Jetpack Compose ใช้การติดตั้งโปรไฟล์สำหรับบิลด์ที่เผยแพร่ โปรแกรมติดตั้งโปรไฟล์ช่วยให้แอปสามารถระบุโค้ดที่สำคัญที่จะคอมไพล์แบบ Ahead-Of-Time (AOT) ณ เวลาที่ติดตั้ง Compose จะจัดส่งกฎการติดตั้งโปรไฟล์ซึ่งช่วยลดเวลาในการเริ่มต้นและการกระตุกในแอป Compose