Overdraw là việc vẽ lại quá mức các pixel giống nhau nhiều lần trong một khung hình. Khi một giao diện phức tạp với nhiều phần tử chồng lấn được hiển thị trên màn hình, GPU buộc phải xử lý từng pixel nhiều lần, ảnh hưởng trực tiếp đến tốc độ khung hình và mức tiêu thụ điện năng. Theo tài liệu Google Android Developer, 2025, giảm overdraw 50% có thể tăng hiệu suất kết xuất lên tới 30%. Tối ưu hóa overdraw là bước bắt buộc khi phát triển ứng dụng có hoạt ảnh mượt mà và giao diện phản hồi nhanh.
Những điểm chính
Overdraw là tình huống cùng một pixel màn hình được vẽ lại nhiều lần trong một khung kết xuất. Trong kịch bản lý tưởng, mỗi pixel chỉ được ghi một lần, nhưng trong giao diện thực tế do các View lồng nhau, hình nền và lớp trong suốt, GPU thực hiện các ghi lặp lại.
Mỗi lần vẽ lại bổ sung làm tăng thời gian kết xuất khung hình. Ở tốc độ 60 FPS tiêu chuẩn, mỗi khung hình có khoảng 16,6 ms. Nếu overdraw khiến vượt quá giới hạn này, tốc độ khung hình giảm xuống 30 FPS hoặc thấp hơn, làm giảm độ mượt của giao diện một cách đáng kể.
Theo Android Performance Patterns của Google, ứng dụng có hệ số overdraw 3x dành gấp ba lần thời gian cho bộ đổ bóng mảnh so với ứng dụng có overdraw 1x. Trên các thiết bị GPU hiệu suất thấp, điều này dẫn đến độ trễ đáng chú ý khi cuộn và hoạt ảnh.
Đối với nhà phát triển di động, hiểu về overdraw là cực kỳ quan trọng: yếu tố này thường gây ra cuộn giật và tốc độ khung hình thấp trên các màn hình có vẻ đơn giản với số lượng lớn phần tử lồng nhau.
Đường ống GPU bao gồm nhiều giai đoạn: bộ đổ bóng đỉnh, rasterization và bộ đổ bóng mảnh. Bộ đổ bóng mảnh là phần tốn kém nhất vì nó thực thi cho mọi pixel của mọi nguyên thủy. Với overdraw 2x, bộ đổ bóng mảnh xử lý gấp đôi số pixel, làm tăng trực tiếp thời gian khung hình.
Các GPU di động hiện đại như Qualcomm Adreno và Apple GPU có cơ chế Early-Z Test và Hidden Surface Removal giúp bù đắp một phần overdraw. Tuy nhiên, các tối ưu hóa này chỉ hoạt động trong điều kiện nhất định và không nên chỉ dựa vào tăng tốc phần cứng.
Ví dụ, khi kết xuất các phần tử bán trong suốt, Early-Z phần cứng không hiệu quả và mỗi pixel được xử lý hoàn toàn — overdraw trong các kịch bản như vậy có thể đạt 5x hoặc cao hơn.
Nền nhiều lớp là một trong những nguyên nhân chính gây overdraw trong ứng dụng di động. Khi Activity hoặc ViewController đặt màu nền, mỗi View lồng nhau có thể thêm nền riêng và pixel được vẽ lại ở mọi cấp phân cấp.
Nghiên cứu của Uber Engineering cho thấy việc loại bỏ nền thừa trong ứng dụng Android của họ đã giảm overdraw 32% và thời gian kết xuất màn hình 25%. Tình trạng tương tự tồn tại trong iOS: đặt opaque = true cho các View không trong suốt loại bỏ pha trộn alpha và ngăn ghi pixel nhiều lần.
Trên nền tảng iOS, overdraw thường xảy ra do sử dụng UIStackView trong suốt, CALayer với shouldRasterize và UIBlurEffect chồng lấn. Apple khuyên nên kiểm tra overdraw thông qua công cụ Core Animation trong XCode — nó hiển thị các khu vực vẽ lại dưới dạng lớp phủ màu đỏ.
Debug GPU Overdraw là công cụ tích hợp của Android tô màu màn hình khác nhau tùy theo hệ số overdraw. Màu tím nghĩa là 1x, xanh dương — 2x, xanh lá — 3x, hồng — 4x, đỏ — 5x hoặc hơn. Màn hình lý tưởng nên chủ yếu là màu tím.
Trong iOS, chẩn đoán tương tự được thực hiện bởi công cụ Core Animation trong XCode Instruments. Nó trực quan hóa các khu vực vẽ lại và hiển thị số lần ghi pixel chính xác ở chế độ Color Blended Layers. Lớp màu xanh lá là không trong suốt (tối ưu), lớp màu đỏ chứa độ trong suốt và gây ra overdraw.
Sau khi chẩn đoán, điều quan trọng là đo FPS trước và sau khi tối ưu hóa. Chênh lệch 10–15 FPS khi sửa overdraw là kết quả bình thường cho màn hình phức tạp có danh sách và hoạt ảnh.
Loại bỏ nền thừa là phương pháp đơn giản và hiệu quả nhất. Trong Android, chỉ cần đặt android:windowBackground cho Activity hoặc chủ đề, không phải cho từng View. Trong iOS, opaque = true cho tất cả UIView không trong suốt giảm overdraw xuống gần như bằng không cho các phần tử đó.
Theo Google I/O 2019, tối ưu hóa overdraw trong Google Maps đã cho phép giảm thời gian kết xuất khung hình 40% thông qua hợp nhất lớp và sử dụng ClipRect để giới hạn khu vực vẽ. Đối với nhà phát triển Android, Google khuyến nghị các thực hành sau:
Trong iOS, tối ưu hóa đạt được thông qua cấu hình CALayer: đặt masksToBounds = true cắt nội dung vượt quá giới hạn lớp và shouldRasterize kích hoạt bộ nhớ đệm bitmap cho các lớp tĩnh.
Hãy xem các ví dụ thực tế bằng Kotlin và Swift minh họa các kịch bản loại bỏ overdraw điển hình. Ví dụ đầu tiên cho thấy tối ưu hóa thông qua ClipRect trong 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)
}
}
Ví dụ thứ hai bằng Swift cho thấy cách vô hiệu hóa độ trong suốt cho một lớp nếu phần tử không nên bán trong suốt:
class OpaqueLabel: UILabel {
override var isOpaque: Bool {
get { true }
set { }
}
override func draw(_ rect: CGRect) {
backgroundColor?.setFill()
UIRectFill(rect)
super.draw(rect)
}
}
Ví dụ thứ ba minh họa sử dụng ViewStub để tải bản đồ trễ trong Android. ViewStub không kết xuất cho đến khi nó trở nên hiển thị, giúp loại bỏ overdraw ở giai đoạn khởi tạo màn hình:
<!-- 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()
Câu hỏi thường gặp
Overdraw là khi một pixel trên màn hình được vẽ lại nhiều lần trong một khung hình. Hãy tưởng tượng bạn đang tô màu một tờ giấy, và dán nhiều phim trong suốt có hình vẽ lên trên — các lớp bên dưới phải được vẽ lại mỗi khi lớp trên cùng thay đổi.
Bật Debug GPU Overdraw trong cài đặt nhà phát triển. Phần tử có overdraw 1x được tô màu tím, 2x — xanh dương, 3x — xanh lá, 4x — hồng, 5x+ — đỏ. Màn hình tối ưu chủ yếu là màu tím không có vùng đỏ.
Mỗi lần vẽ lại pixel bổ sung yêu cầu gọi bộ đổ bóng mảnh, xử lý màu sắc, kết cấu và ánh sáng. Ở 60 FPS, mỗi khung hình có 16,6 ms — nếu overdraw buộc GPU xử lý gấp 2–3 lần số pixel, vượt quá giới hạn và FPS giảm xuống 30.
Có, trực tiếp. GPU thực hiện công việc quá mức tiêu thụ nhiều năng lượng hơn. Theo nghiên cứu của Google, giảm overdraw từ 4x xuống 1x làm giảm mức tiêu thụ điện năng GPU 35–50%, đặc biệt đáng chú ý trên màn hình độ phân giải cao.
Cho màn hình đơn giản — 1x–1,5x (tím với một lượng nhỏ xanh dương). Cho giao diện phức tạp — lên tới 2x. Mức 3x trở lên (hồng, đỏ) yêu cầu tối ưu hóa. Google khuyến nghị không vượt quá trung bình 2,5x overdraw trên toàn màn hình.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm