Overdraw คือการวาดพิกเซลเดียวกันซ้ำหลายครั้งต่อเฟรมมากเกินไป เมื่ออินเทอร์เฟซที่ซับซ้อนซึ่งมีองค์ประกอบที่ทับซ้อนกันจำนวนมากแสดงบนหน้าจอ GPU ต้องประมวลผลแต่ละพิกเซลซ้ำๆ ซึ่งส่งผลโดยตรงต่ออัตราเฟรมและการใช้พลังงาน ตาม เอกสารของ Google Android Developer, 2025 การลด overdraw 50% สามารถเพิ่มประสิทธิภาพการเรนเดอร์ได้ถึง 30% การปรับปรุง overdraw เป็นขั้นตอนบังคับเมื่อพัฒนาแอปพลิเคชันที่มีแอนิเมชันลื่นไหลและอินเทอร์เฟซที่ตอบสนองรวดเร็ว
ประเด็นสำคัญ
Overdraw คือสถานการณ์ที่พิกเซลหน้าจอเดียวกันถูกวาดซ้ำหลายครั้งภายในเฟรมการเรนเดอร์เดียว ในสถานการณ์ที่เหมาะสม พิกเซลแต่ละตัวควรถูกเขียนเพียงครั้งเดียว แต่ในอินเทอร์เฟซจริงเนื่องจากการซ้อนกันของ Views รูปภาพพื้นหลัง และเลเยอร์โปร่งใส GPU จึงทำการเขียนซ้ำ
การวาดซ้ำแต่ละครั้งเพิ่มเวลาเรนเดอร์เฟรม ที่อัตรามาตรฐาน 60 FPS แต่ละเฟรมมีเวลาประมาณ 16.6 มิลลิวินาที หาก overdraw ทำให้เกินขีดจำกัดนี้ อัตราเฟรมจะลดลงเหลือ 30 FPS หรือต่ำกว่า ซึ่งทำให้ความลื่นไหลของอินเทอร์เฟซลดลงอย่างเห็นได้ชัด
ตาม Android Performance Patterns ของ Google แอปที่มีปัจจัย overdraw 3x ใช้เวลาใน Fragment Shader มากกว่าแอปที่มี overdraw 1x ถึงสามเท่า บนอุปกรณ์ GPU ที่มีประสิทธิภาพต่ำ สิ่งนี้นำไปสู่ความหน่วงที่สังเกตได้ระหว่างการเลื่อนและแอนิเมชัน
สำหรับนักพัฒนาโมบายล์ การทำความเข้าใจ overdraw มีความสำคัญอย่างยิ่ง: ปัจจัยนี้มักทำให้เกิดการเลื่อนกระตุกและอัตราเฟรมต่ำในหน้าจอที่ดูเรียบง่ายซึ่งมีองค์ประกอบที่ซ้อนกันจำนวนมาก
ไปป์ไลน์ของ GPU ประกอบด้วยหลายขั้นตอน: Vertex Shader, Rasterization และ Fragment Shader Fragment Shader เป็นส่วนที่แพงที่สุดเนื่องจากทำงานทุกพิกเซลของทุกไพร มิทีฟ ที่ overdraw 2x Fragment Shader จะประมวลผลพิกเซลเป็นสองเท่า ซึ่งเพิ่มเวลาเฟรมโดยตรง
GPU มือถือสมัยใหม่ เช่น Qualcomm Adreno และ Apple GPU มีกลไก Early-Z Test และ Hidden Surface Removal ที่ชดเชย overdraw บางส่วน อย่างไรก็ตาม การปรับปรุงเหล่านี้ทำงานภายใต้เงื่อนไขบางประการเท่านั้น และไม่ควรพึ่งพาการเร่งด้วยฮาร์ดแวร์เพียงอย่างเดียว
ตัวอย่างเช่น เมื่อเรนเดอร์องค์ประกอบกึ่งโปร่งใส Early-Z ของฮาร์ดแวร์ไม่มีประสิทธิภาพ และแต่ละพิกเซลถูกประมวลผลอย่างสมบูรณ์ — overdraw ในสถานการณ์เช่นนี้สามารถสูงถึง 5x หรือมากกว่า
พื้นหลังหลายชั้น เป็นหนึ่งในสาเหตุหลักของ overdraw ในแอปมือถือ เมื่อ Activity หรือ ViewController กำหนดสีพื้นหลัง View ที่ซ้อนกันแต่ละตัวสามารถเพิ่มพื้นหลังของตัวเอง และพิกเซลจะถูกวาดซ้ำในทุกระดับของลำดับชั้น
การศึกษาของ Uber Engineering แสดงให้เห็นว่าการลบพื้นหลังที่มากเกินไปในแอป Android ของพวกเขาลด overdraw ลง 32% และเวลาเรนเดอร์หน้าจอลง 25% สถานการณ์คล้ายกันใน iOS: การตั้งค่า opaque = true สำหรับ View ที่ไม่โปร่งใสจะกำจัดการผสมอัลฟาและป้องกันการเขียนพิกเซลหลายครั้ง
บนแพลตฟอร์ม iOS overdraw มักเกิดขึ้นเนื่องจากการใช้ UIStackView โปร่งใส CALayer ที่มี shouldRasterize และ UIBlurEffect ที่ทับซ้อนกัน Apple แนะนำให้ตรวจสอบ overdraw ผ่านเครื่องมือ Core Animation ใน XCode — มันแสดงโซนการวาดซ้ำเป็นชั้นซ้อนทับสีแดง
Debug GPU Overdraw เป็นเครื่องมือในตัวของ Android ที่ทำให้หน้าจอเป็นสีต่างๆ ตามปัจจัย overdraw สีม่วงหมายถึง 1x, สีน้ำเงิน — 2x, สีเขียว — 3x, สีชมพู — 4x, สีแดง — 5x หรือมากกว่า หน้าจอที่เหมาะสมควรเป็นสีม่วงเป็นส่วนใหญ่
ใน iOS การวินิจฉัยที่คล้ายกันดำเนินการโดยเครื่องมือ Core Animation ใน XCode Instruments มันแสดงโซนการวาดซ้ำและแสดงจำนวนการเขียนพิกเซลที่แน่นอนในโหมด Color Blended Layers เลเยอร์สีเขียวทึบแสง (เหมาะสมที่สุด) เลเยอร์สีแดงมีความโปร่งใสและทำให้เกิด overdraw
หลังการวินิจฉัย สิ่งสำคัญคือวัด FPS ก่อนและหลังการปรับปรุง ความแตกต่าง 10–15 FPS เมื่อแก้ไข overdraw เป็นผลลัพธ์ปกติสำหรับหน้าจอที่ซับซ้อนพร้อมรายการและแอนิเมชัน
การลบพื้นหลังที่มากเกินไป เป็นวิธีที่ง่ายและมีประสิทธิภาพที่สุด ใน Android เพียงตั้งค่า android:windowBackground สำหรับ Activity หรือธีมเท่านั้น ไม่ใช่สำหรับแต่ละ View ใน iOS opaque = true สำหรับ UIView ที่ไม่โปร่งใสทั้งหมดจะลด overdraw เหลือเกือบศูนย์สำหรับองค์ประกอบเหล่านั้น
ตาม Google I/O 2019 การปรับปรุง overdraw ใน Google Maps ช่วยลดเวลาเรนเดอร์เฟรมลง 40% ผ่านการรวมเลเยอร์และการใช้ ClipRect เพื่อจำกัดพื้นที่วาด สำหรับนักพัฒนา Android Google แนะนำแนวทางปฏิบัติต่อไปนี้:
ใน iOS การปรับปรุงทำได้ผ่านการกำหนดค่า CALayer: การตั้งค่า masksToBounds = true จะตัดเนื้อหาที่เกินขอบเขตเลเยอร์ และ shouldRasterize เปิดใช้งานแคชบิตแมปสำหรับเลเยอร์แบบคงที่
มาดูตัวอย่างเชิงปฏิบัติใน Kotlin และ Swift ที่แสดงสถานการณ์การกำจัด overdraw ทั่วไป ตัวอย่างแรกแสดงการปรับปรุงผ่าน ClipRect ใน Android:
class OptimizedView@JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {
override fun onDraw(canvas: Canvas) {
canvas.clipRect(
paddingLeft.toFloat(), paddingTop.toFloat(),
width - paddingRight.toFloat(), height - paddingBottom.toFloat()
)
// Draw content only within clipped area
super.onDraw(canvas)
}
}
ตัวอย่างที่สองใน Swift แสดงการปิดความโปร่งใสสำหรับเลเยอร์หากองค์ประกอบไม่ควรกึ่งโปร่งใส:
class OpaqueLabel: UILabel {
override var isOpaque: Bool {
get { true }
set { }
}
override func draw(_ rect: CGRect) {
backgroundColor?.setFill()
UIRectFill(rect)
super.draw(rect)
}
}
ตัวอย่างที่สามสาธิตการใช้ ViewStub สำหรับการโหลดแผนที่แบบเลื่อนออกไปใน Android ViewStub จะไม่เรนเดอร์จนกว่าจะมองเห็น ซึ่งกำจัด overdraw ในขั้นตอนการเริ่มต้นหน้าจอ:
<!-- layout/activity_main.xml -->
<ViewStub
android:id="@+id/map_stub"
android:layout_width="match_parent"
android:layout_height="200dp"
android:inflatedId="@+id/map_container"
android:layout="@layout/map_fragment" />
// Inflate on demand
ViewStub stub = findViewById(R.id.map_stub)
stub?.inflate()
คำถามที่พบบ่อย
Overdraw คือเมื่อพิกเซลบนหน้าจอถูกวาดซ้ำหลายครั้งในหนึ่งเฟรม ลองนึกภาพคุณกำลังระบายสีแผ่นกระดาษ แล้วติดฟิล์มโปร่งใสที่มีลายหลายแผ่นทับด้านบน — เลเยอร์ด้านล่างต้องถูกวาดซ้ำทุกครั้งที่เลเยอร์ด้านบนเปลี่ยนแปลง
เปิด Debug GPU Overdraw ในการตั้งค่านักพัฒนา องค์ประกอบที่มี overdraw 1x จะเป็นสีม่วง, 2x — สีน้ำเงิน, 3x — สีเขียว, 4x — สีชมพู, 5x+ — สีแดง หน้าจอที่เหมาะสมควรเป็นสีม่วงเป็นส่วนใหญ่ไม่มีบริเวณสีแดง
การวาดพิกเซลซ้ำแต่ละครั้งต้องเรียก Fragment Shader ซึ่งประมวลผลสี พื้นผิว และแสง ที่ 60 FPS แต่ละเฟรมมี 16.6 มิลลิวินาที — หาก overdraw บังคับให้ GPU ประมวลผลพิกเซลมากกว่า 2–3 เท่า ขีดจำกัดจะเกินและ FPS ลดลงเหลือ 30
ใช่ โดยตรง GPU ที่ทำงานมากเกินไปใช้พลังงานมากขึ้น ตามการวิจัยของ Google การลด overdraw จาก 4x เป็น 1x ลดการใช้พลังงาน GPU ลง 35–50% ซึ่งสังเกตได้ชัดเจนบนจอแสดงผลความละเอียดสูง
สำหรับหน้าจอธรรมดา — 1x–1.5x (สีม่วงมีสีน้ำเงินเล็กน้อย) สำหรับอินเทอร์เฟซที่ซับซ้อน — สูงถึง 2x ระดับ 3x ขึ้นไป (สีชมพู สีแดง) ต้องการการปรับปรุง Google แนะนำไม่ให้เกินเฉลี่ย 2.5x overdraw ทั่วทั้งหน้าจอ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม