Overdraw — ugyanazon pixelek túlzott többszöri újrarajzolása egyetlen képkockán belül. Amikor egy összetett felület sok átfedő elemmel jelenik meg a képernyőn, a GPU kénytelen minden pixelt többször feldolgozni, ami közvetlenül befolyásolja a képkockasebességet és az energiafogyasztást. A Google Android Developer Documentation, 2025 szerint az overdraw 50%-os csökkentése akár 30%-kal is növelheti a renderelési teljesítményt. Az overdraw optimalizálása kötelező lépés a sima animációkkal és reszponzív felülettel rendelkező alkalmazások fejlesztése során.
Főbb pontok
Overdraw — az a helyzet, amikor ugyanazt a képernyőpixelt többször újrarajzolják egyetlen renderelési képkocka során. Ideális esetben minden pixelt pontosan egyszer kellene írni, de a valós felületekben az egymásba ágyazott View-k, háttérképek és átlátszó rétegek miatt a GPU ismételt írásokat végez.
Minden további újrarajzolás növeli a képkocka renderelési idejét. 60 FPS szabványos frekvenciánál körülbelül 16.6 ms áll rendelkezésre egy képkocka feldolgozására. Ha az overdraw ezt a határt túllépi, a képkockasebesség 30 FPS-re vagy alacsonyabbra csökken, ami észrevehetően rontja a felület simaságát.
A Google Android Performance Patterns szerint egy 3x overdraw együtthatójú alkalmazás háromszor több időt tölt a fragment shaderrel, mint egy 1x overdraw-del rendelkező alkalmazás. Alacsony GPU-teljesítményű eszközökön ez érezhető lag-ekhez vezet görgetés és animációk során.
A mobil fejlesztők számára az overdraw megértése kritikus fontosságú: pontosan ez a tényező okozza leggyakrabban a rángatózó görgetést és az alacsony képkockasebességet a látszólag egyszerű, de sok egymásba ágyazott elemet tartalmazó képernyőkön.
A GPU csővezeték több szakaszból áll: vertex shader, raszterizáció és fragment shader. Fragment shader — a legköltségesebb rész, mivel minden primitív minden pixele esetében végrehajtódik. Overdraw x2 esetén a fragment shader kétszer annyi pixelt dolgoz fel, ami közvetlenül növeli a képkocka időt.
A modern mobil GPU-k, mint a Qualcomm Adreno és az Apple GPU, rendelkeznek Early-Z Test és Hidden Surface Removal mechanizmusokkal, amelyek részben kompenzálják az overdrawn-t. Ezek az optimalizálások azonban csak bizonyos körülmények között működnek, és nem szabad kizárólag a hardveres gyorsításra hagyatkozni.
Például a félig átlátszó elemek renderelésekor a hardveres Early-Z nem hatékony, és minden pixelt teljesen feldolgoznak — az overdraw ilyen forgatókönyvekben elérheti az 5x-et és még többet.
Többrétegű hátterek — az overdraw egyik fő oka a mobil alkalmazásokban. Amikor egy Activity vagy ViewController háttérszínt állít be, minden egymásba ágyazott View hozzáadhatja saját hátterét, és a pixel a hierarchia minden szintjén újrarajzolódik.
Az Uber Engineering kutatása kimutatta, hogy a felesleges hátterek eltávolítása Android-alkalmazásukban 32%-kal csökkentette az overdrawn-t, és 25%-kal a képernyő renderelési idejét. Hasonló a helyzet iOS-ben: az opaque = true beállítása az átlátszatlan View-k esetében megszünteti az alfa-keverést és megakadályozza a pixelek többszöri írását.
Az iOS platformon az overdraw gyakran az átlátszó UIStackView, a shouldRasterize-tel rendelkező CALayer és az átfedő UIBlurEffect használata miatt alakul ki. Az Apple az overdraw ellenőrzését a Core Animation eszközzel javasolja az XCode-ban — ez piros fedvényként mutatja az újrarajzolási zónákat.
Debug GPU Overdraw — az Android beépített eszköze, amely az overdraw többszörösségétől függően különböző színekre festi a képernyőt. A lila szín 1x-et, a kék — 2x-et, a zöld — 3x-et, a rózsaszín — 4x-et, a piros — 5x-et és többet jelent. Az ideális képernyőnek túlnyomórészt lilának kell lennie.
Az iOS-ben hasonló diagnosztikát végez a Core Animation eszköz az XCode Instruments részeként. Vizualizálja az újrarajzolási zónákat és megmutatja a pixelenkénti írások pontos számát Color Blended Layers módban. A zöld rétegek — átlátszatlanok (optimálisak), a pirosak — átlátszóságot tartalmaznak és overdrawn-t okoznak.
A diagnosztika után fontos az FPS mérése az optimalizálás előtt és után. 10–15 FPS különbség az overdraw javításakor normális eredmény egy összetett, listákkal és animációval rendelkező képernyő esetében.
Felesleges hátterek eltávolítása — a legegyszerűbb és leghatékonyabb módszer. Androidban elég az android:windowBackground beállítása csak az Activity vagy a témához, nem minden View-hoz. iOS-ben az opaque = true az összes átlátszatlan UIView esetében gyakorlatilag nullára csökkenti az overdrawn-t ezeknél az elemeknél.
A Google I/O 2019 szerint az overdraw optimalizálása a Google Maps-ben lehetővé tette a képkocka renderelési idő 40%-os csökkentését a rétegek összevonásával és a ClipRect használatával a rajzolási terület korlátozására. A Google a következő gyakorlatokat ajánlja az Android fejlesztőknek:
Az iOS-ben az optimalizálás a CALayer konfigurációjával érhető el: a masksToBounds = true beállítása levágja a réteg határain túli tartalmat, a shouldRasterize pedig bekapcsolja a raszteres megjelenítés gyorsítótárazását a statikus rétegek számára.
Tekintsük át a gyakorlati példákat Kotlin és Swift nyelven, amelyek bemutatják az overdraw eltávolításának tipikus forgatókönyveit. Az első példa az optimalizálást mutatja ClipRect segítségével Androidban:
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()
)
// Tartalom rajzolása csak a vágott területen belül
super.onDraw(canvas)
}
}
A második példa — Swift nyelven, az átlátszóság kikapcsolását mutatja egy réteg esetében, ha az elem nem lehet félig átlátszó:
class OpaqueLabel: UILabel {
override var isOpaque: Bool {
get { true }
set { }
}
override func draw(_ rect: CGRect) {
backgroundColor?.setFill()
UIRectFill(rect)
super.draw(rect)
}
}
A harmadik példa — a ViewStub használata a térkép késleltetett betöltéséhez Androidban. A ViewStub nem renderelődik, amíg láthatóvá nem válik, ami megszünteti az overdrawn-t a képernyő inicializálási szakaszában:
<!-- 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" />
// Kiterjesztés igény szerint
ViewStub stub = findViewById(R.id.map_stub)
stub?.inflate()
Gyakran ismételt kérdések
Overdraw — amikor egy képernyőpixelt többször újrarajzolnak egyetlen képkocka alatt. Képzelje el, hogy fest egy papírlapot, és ráragaszt néhány átlátszó fóliát rajzokkal — az alsó rétegeket minden alkalommal újra kell rajzolni, amikor a felső réteg megváltozik.
Kapcsolja be a Debug GPU Overdraw opciót a fejlesztői beállításokban. Az 1x overdraw-del rendelkező elemek lila, 2x — kék, 3x — zöld, 4x — rózsaszín, 5x+ — piros színűek. Az optimális képernyő túlnyomórészt lila, piros zónák nélkül.
Minden további pixel-újrarajzolás megköveteli a fragment shader meghívását, amely feldolgozza a színt, textúrát és világítást. 60 FPS-nél képkockánként 16.6 ms áll rendelkezésre — ha az overdraw a GPU-t 2–3-szor több pixel feldolgozására kényszeríti, a határ túllépésre kerül, és az FPS 30-ra esik.
Igen, közvetlenül. A túlzott munkát végző GPU több energiát fogyaszt. A Google kutatása szerint az overdraw 4x-ről 1x-re csökkentése 35–50%-kal csökkenti a GPU energiafogyasztását, ami különösen észrevehető a nagy felbontású kijelzővel rendelkező eszközökön.
Egyszerű képernyők esetén — 1x–1.5x (lila kis mennyiségű kékkel). Gazdag felületek esetén — 2x-ig. A 3x és magasabb szint (rózsaszín, piros) optimalizálást igényel. A Google azt javasolja, hogy átlagosan ne haladja meg a 2.5x overdraw szintet képernyőnként.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is