What is overdraw, and how do you find and fix it?
The same pixel gets painted three, four, five times a frame — invisible in a screenshot, brutal on a mid-range phone's GPU.
LEARN BY DOINGPut your intuition to work3 steps
What is overdraw, and how do you find and fix it?
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.#What overdraw actually is
Overdraw is the GPU painting the same pixel more than once in a single frame. Every opaque or translucent layer you stack on screen — a background, a card behind it, a scrim behind that, a shadow behind that — costs a full fill of the pixels it covers, even the ones a layer above will completely hide a moment later. The frame that finally reaches the display only needed the top layer's color at that pixel; everything underneath was wasted GPU work.
A little overdraw is normal and free: a button drawn once on top of a screen background is one extra pass over a small area, and no phone will notice. The problem is compounding overdraw — nested backgrounds, a full-screen scrim under a dialog that's under another full-screen container, or a list where every row draws its own opaque background on top of a window background that was never going to show through anywhere. On a flagship SoC this is often invisible because the GPU has fill-rate to spare. On a mid-range or budget device — which is most of your install base outside a handful of markets — 3-4x overdraw on a full screen is enough to visibly drop frames during a scroll or a transition, because fill rate, not raw compute, becomes the bottleneck.
#How you find it
On Android, Developer Options has a literal "Debug GPU Overdraw" toggle that recolors the live UI: true color means no overdraw, blue means one extra layer, green means two, light red three, dark red four or more. You turn it on, open the screen you suspect, and look for red — it is exactly as visual as it sounds, and it is the fastest way to build intuition for which of your own layout choices are expensive. iOS doesn't ship an equivalent color overlay, but Instruments' Core Animation tool has a "Color Blended Layers" option that highlights non-opaque layers being blended, which is the iOS analogue for the blending half of the problem (translucency, not opacity stacking, is the more common overdraw source there because UIKit/SwiftUI views are opaque by default unless you set a translucent background or alpha).
Beyond the visual tools, a frame-timing profiler (Android GPU Profiler / Perfetto's frame timeline, or Instruments' Core Animation FPS + GPU counters) will show fragment/GPU time spiking on screens with heavy view stacking, which is the quantitative confirmation that what you saw as red in the overdraw view is actually costing frame budget.
#How you fix it
The fixes all reduce to "stop painting pixels nobody will see":
- Remove redundant backgrounds. The most common offender is a background color set on a root container, then again on every child container, then again on every list row — when only the outermost one (or none, if the window background already provides it) is ever visible.
- Flatten the view hierarchy. Fewer nested, individually-backgrounded containers means fewer full-area fills stacked on top of each other. This is also why
ConstraintLayout(Android) or a flatter SwiftUI view tree tends to outperform deep nesting even before overdraw enters the picture — fewer layout passes and fewer draw passes both improve. - Use
clipRect/clipping and opaque windows where you can. If a view is guaranteed to be fully covered, you can hint the renderer to skip drawing it (Android'sView.setWillNotDraw, or trimming a customonDrawto only paint the visible region). - Avoid unnecessary translucency. Alpha blending is inherently more expensive than an opaque fill because the GPU has to composite with what's beneath rather than simply overwrite it. A translucent scrim under a dialog is fine; a chain of five translucent cards stacked over each other is not.
- Prefer a single flattened background asset or color over stacking drawables — a nine-patch with a shadow baked in, rather than a shadow view plus a card view plus a background view all layered live.
The deeper point for an interview: overdraw is a fill-rate problem, distinct from layout/measure cost or from jank caused by heavy work on the main thread. A senior answer distinguishes these — a screen can have a cheap view hierarchy to measure and lay out, yet still be GPU-bound purely from stacked, mostly-hidden paints. Naming that distinction, and knowing which tool diagnoses which, is what separates "I've heard of overdraw" from "I've actually fixed it in a shipped app."