การทำงานกับรูปภาพอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้อย่างรวดเร็วหากคุณไม่ระมัดระวัง คุณอาจพบ OutOfMemoryError
ได้อย่างง่ายดายเมื่อทำงานกับบิตแมปขนาดใหญ่ ทําตามแนวทางปฏิบัติแนะนำเหล่านี้เพื่อให้แอปทำงานได้ดีที่สุด
โหลดเฉพาะขนาดบิตแมปที่ต้องการ
สมาร์ทโฟนส่วนใหญ่มีกล้องความละเอียดสูงที่ผลิตไฟล์ภาพขนาดใหญ่ หากแสดงรูปภาพบนหน้าจอ คุณต้องลดความละเอียดของรูปภาพหรือโหลดรูปภาพให้มีขนาดไม่เกินขนาดของคอนเทนเนอร์รูปภาพเท่านั้น การโหลดรูปภาพที่มีขนาดใหญ่กว่าที่จำเป็นอย่างต่อเนื่องอาจทำให้แคช GPU หมดลง ซึ่งส่งผลให้การแสดงผล UI มีประสิทธิภาพต่ำลง
วิธีจัดการขนาดรูปภาพ
- ปรับขนาดไฟล์ภาพให้เล็กที่สุดเท่าที่จะทำได้ (โดยไม่ส่งผลต่อรูปภาพเอาต์พุต)
- ลองแปลงรูปภาพเป็นรูปแบบ WEBP แทน JPEG หรือ PNG
- ใส่รูปภาพขนาดที่เล็กลงสำหรับความละเอียดหน้าจอที่แตกต่างกัน (ดูเคล็ดลับ #3)
- ใช้ไลบรารีการโหลดรูปภาพ ซึ่งจะปรับขนาดรูปภาพให้พอดีกับขนาดของมุมมองบนหน้าจอ ซึ่งจะช่วยปรับปรุงประสิทธิภาพการโหลดของหน้าจอ
ใช้เวกเตอร์แทนบิตแมปเมื่อเป็นไปได้
เมื่อแสดงภาพบนหน้าจอ คุณต้องตัดสินใจว่าสามารถแสดงเป็นเวกเตอร์ได้หรือไม่ เลือกใช้ภาพเวกเตอร์มากกว่าบิตแมป เนื่องจากภาพจะไม่แตกเป็นพิกเซลเมื่อปรับขนาดเป็นขนาดต่างๆ อย่างไรก็ตาม ทุกสิ่งสามารถใช้แทนเวกเตอร์ได้ - รูปภาพที่ถ่ายด้วยกล้องถ่ายรูปไม่สามารถแปลงเป็นเวกเตอร์ได้
ระบุทรัพยากรทางเลือกสำหรับหน้าจอขนาดต่างๆ
หากคุณจัดส่งรูปภาพด้วยแอป ลองใส่เนื้อหาที่มีขนาดต่างกันสำหรับอุปกรณ์ที่มีความละเอียดแตกต่างกัน ซึ่งจะช่วยลดความจําเป็นในการดาวน์โหลดแอปในอุปกรณ์ และปรับปรุงประสิทธิภาพเนื่องจากจะโหลดรูปภาพที่มีความละเอียดต่ำลงในอุปกรณ์ที่มีความละเอียดต่ำ ดูเอกสารประกอบเกี่ยวกับบิตแมปทางเลือกเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับการระบุบิตแมปทางเลือกสำหรับอุปกรณ์ขนาดต่างๆ
เมื่อใช้ ImageBitmap
โปรดโทรหา prepareToDraw
ก่อนวาด
เมื่อใช้ ImageBitmap
ให้เรียก ImageBitmap#prepareToDraw()
ก่อนวาดภาพจริงเพื่อเริ่มกระบวนการอัปโหลดพื้นผิวไปยัง GPU วิธีนี้จะช่วยให้ GPU เตรียมพื้นผิวและปรับปรุงประสิทธิภาพในการแสดงภาพบนหน้าจอ ไลบรารีการโหลดรูปภาพส่วนใหญ่จะเพิ่มประสิทธิภาพนี้อยู่แล้ว แต่คุณควรคำนึงถึงเรื่องนี้ด้วยหากใช้คลาส ImageBitmap
ด้วยตนเอง
โปรดส่ง Int
DrawableRes
หรือ URL เป็นพารามิเตอร์ไปยังคอมโพสิเบิลแทน Painter
เนื่องจากความซับซ้อนของการจัดการกับรูปภาพ (เช่น การเขียนฟังก์ชันเท่ากับสำหรับ Bitmaps
จะใช้เวลาในการประมวลผลมาก) ระบบจึงไม่ได้ทําเครื่องหมาย Painter
API เป็นคลาสเสถียรอย่างชัดเจน คลาสที่ไม่เสถียรอาจทําให้ต้องมีการคอมไพล์ใหม่โดยไม่จําเป็น เนื่องจากคอมไพเลอร์ไม่สามารถอนุมานได้ง่ายๆ ว่าข้อมูลมีการเปลี่ยนแปลงหรือไม่
ดังนั้นจึงควรส่ง URL หรือรหัสทรัพยากรที่ถอนออกได้เป็นพารามิเตอร์ไปยัง Composable แทนการส่ง Painter
เป็นพารามิเตอร์
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
อย่าจัดเก็บบิตแมปในหน่วยความจํานานเกินกว่าที่จําเป็น
ยิ่งคุณโหลดบิตแมปลงในหน่วยความจำมากเท่าใด หน่วยความจำบนอุปกรณ์ก็ยิ่งเต็มมากขึ้นเท่านั้น ตัวอย่างเช่น หากโหลดรายการ Composable ของรูปภาพจำนวนมากบนหน้าจอ ให้ใช้ LazyColumn
หรือ LazyRow
เพื่อให้แน่ใจว่าหน่วยความจำว่างเมื่อเลื่อนรายการขนาดใหญ่
อย่ารวมไฟล์ภาพขนาดใหญ่ไว้ในไฟล์ AAB/APK
สาเหตุหลักประการหนึ่งที่ทำให้แอปมีขนาดใหญ่เมื่อดาวน์โหลดคือกราฟิกที่แพ็กเกจไว้ในไฟล์ AAB หรือ APK ใช้เครื่องมือเครื่องมือวิเคราะห์ APK เพื่อให้แน่ใจว่าคุณไม่ได้แพ็กเกจไฟล์ภาพที่มีขนาดใหญ่กว่าที่กำหนด ลดขนาดหรือลองวางรูปภาพไว้ในเซิร์ฟเวอร์และดาวน์โหลดเฉพาะเมื่อจำเป็น
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ImageBitmap กับ ImageVector {:#bitmap-vs-vector}
- บันทึกสถานะ UI ใน Compose
- ระยะของ Jetpack Compose