การเพิ่มประสิทธิภาพสำหรับรูปภาพ

การทำงานกับรูปภาพอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้อย่างรวดเร็วหากคุณไม่ระมัดระวัง คุณอาจพบ OutOfMemoryError ได้ง่ายเมื่อทำงานกับบิตแมปขนาดใหญ่ ทําตามแนวทางปฏิบัติแนะนำเหล่านี้เพื่อให้แอปทำงานได้ดีที่สุด

โหลดเฉพาะขนาดบิตแมปที่ต้องการ

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

วิธีจัดการขนาดรูปภาพ

  • ปรับขนาดไฟล์ภาพให้เล็กที่สุดเท่าที่จะทำได้ (โดยไม่ส่งผลต่อรูปภาพเอาต์พุต)
  • ลองแปลงรูปภาพเป็นรูปแบบ WEBP แทน JPEG หรือ PNG
  • ระบุรูปภาพที่มีขนาดเล็กลงสำหรับความละเอียดหน้าจอที่แตกต่างกัน (ดูเคล็ดลับ #3)
  • ใช้ไลบรารีการโหลดรูปภาพ ซึ่งจะปรับขนาดรูปภาพให้พอดีกับขนาดของมุมมองบนหน้าจอ ซึ่งจะช่วยปรับปรุงประสิทธิภาพการโหลดของหน้าจอ

ใช้เวกเตอร์แทนบิตแมปเมื่อเป็นไปได้

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

ระบุแหล่งข้อมูลสำรองสำหรับหน้าจอขนาดต่างๆ

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

เมื่อใช้ ImageBitmap ให้เรียกใช้ prepareToDraw ก่อนวาด

เมื่อใช้ ImageBitmap ให้เรียก ImageBitmap#prepareToDraw() ก่อนวาดภาพจริงเพื่อเริ่มกระบวนการอัปโหลดพื้นผิวไปยัง GPU ซึ่งจะช่วยให้ GPU เตรียมพื้นผิวและปรับปรุงประสิทธิภาพการแสดงภาพบนหน้าจอ ไลบรารีการโหลดรูปภาพส่วนใหญ่จะเพิ่มประสิทธิภาพนี้อยู่แล้ว แต่คุณควรคำนึงถึงเรื่องนี้ด้วยหากใช้คลาส ImageBitmap ด้วยตนเอง

โปรดส่ง Int DrawableRes หรือ URL เป็นพารามิเตอร์ไปยังคอมโพสิเบิลแทน Painter

เนื่องจากความซับซ้อนของการจัดการกับรูปภาพ (เช่น การเขียนฟังก์ชันเท่ากับสำหรับ Bitmaps จะใช้เวลาในการประมวลผลมาก) ระบบจึงไม่ได้ทําเครื่องหมาย Painter API เป็นคลาสเสถียรอย่างชัดเจน คลาสที่ไม่เสถียรอาจทําให้ต้องมีการคอมไพล์ใหม่โดยไม่จําเป็น เนื่องจากคอมไพเลอร์ไม่สามารถอนุมานได้ง่ายๆ ว่าข้อมูลมีการเปลี่ยนแปลงหรือไม่

ดังนั้น คุณควรส่ง URL หรือรหัสทรัพยากรที่วาดได้เพื่อเป็นพารามิเตอร์ให้กับคอมโพสิเบิลแทนการส่ง Painter เป็นพารามิเตอร์

// Prefer this:
@Composable
fun MyImage(url: String) {

}
// Over this:
@Composable
fun MyImage(painter: Painter) {

}

อย่าจัดเก็บบิตแมปในหน่วยความจํานานเกินกว่าที่จําเป็น

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

อย่ารวมไฟล์ภาพขนาดใหญ่ไว้ในไฟล์ AAB/APK

สาเหตุหลักประการหนึ่งที่ทำให้แอปมีขนาดใหญ่เมื่อดาวน์โหลดคือกราฟิกที่แพ็กเกจไว้ในไฟล์ AAB หรือ APK ใช้เครื่องมือเครื่องมือวิเคราะห์ APK เพื่อให้แน่ใจว่าคุณไม่ได้แพ็กเกจไฟล์ภาพที่มีขนาดใหญ่กว่าที่กำหนด ลดขนาดหรือลองวางรูปภาพไว้ในเซิร์ฟเวอร์และดาวน์โหลดเฉพาะเมื่อจำเป็น