¿Qué es el overdraw y cómo lo detectas y lo arreglas?
El mismo píxel se pinta tres, cuatro, cinco veces por frame — invisible en una captura de pantalla, brutal para la GPU de un teléfono gama media.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
¿Qué es el overdraw y cómo lo detectas y lo arreglas?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.#Qué es realmente el overdraw
El overdraw ocurre cuando la GPU pinta el mismo píxel más de una vez en un solo frame. Cada capa opaca o translúcida que apilas en pantalla —un fondo, una tarjeta detrás, un scrim detrás de esa, una sombra detrás de esa— cuesta un relleno completo de los píxeles que cubre, incluso los que una capa superior va a ocultar por completo un instante después. El frame que finalmente llega a la pantalla solo necesitaba el color de la capa superior en ese píxel; todo lo de abajo fue trabajo de GPU desperdiciado.
Un poco de overdraw es normal y gratis: un botón dibujado una vez sobre el fondo de una pantalla es un pase extra sobre un área pequeña, y ningún teléfono lo va a notar. El problema es el overdraw que se acumula —fondos anidados, un scrim de pantalla completa bajo un diálogo que está bajo otro contenedor de pantalla completa, o una lista donde cada fila dibuja su propio fondo opaco encima de un fondo de ventana que nunca iba a ser visible en ningún lado—. En un SoC de gama alta esto suele ser invisible porque la GPU tiene fill-rate de sobra. En un dispositivo de gama media o baja —que es la mayor parte de tu base instalada fuera de un puñado de mercados— un overdraw de 3-4x en pantalla completa alcanza para perder frames de forma visible durante un scroll o una transición, porque el fill rate, no el cómputo bruto, se convierte en el cuello de botella.
#Cómo lo detectas
En Android, las Opciones de Desarrollador tienen un toggle literal "Debug GPU Overdraw" que recolorea la UI en vivo: color real significa sin overdraw, azul una capa extra, verde dos, rojo claro tres, rojo oscuro cuatro o más. Lo activas, abres la pantalla sospechosa y buscas el rojo —es tan visual como suena, y es la forma más rápida de construir intuición sobre qué decisiones de layout propias son costosas—. iOS no trae un overlay de color equivalente, pero la herramienta Core Animation de Instruments tiene una opción "Color Blended Layers" que resalta las capas no opacas que se están mezclando, que es el análogo en iOS para la mitad del problema relacionada con blending (la translucidez, no el apilamiento de capas opacas, es la fuente de overdraw más común ahí porque las vistas de UIKit/SwiftUI son opacas por defecto salvo que fijes un fondo translúcido o un alpha).
Más allá de las herramientas visuales, un profiler de timing de frames (GPU Profiler de Android / la línea de tiempo de frames de Perfetto, o el FPS + contadores de GPU de Core Animation en Instruments) va a mostrar picos de tiempo de fragmento/GPU en pantallas con apilamiento pesado de vistas, que es la confirmación cuantitativa de que lo que viste en rojo en la vista de overdraw realmente está costando presupuesto de frame.
#Cómo lo arreglas
Todos los arreglos se reducen a "dejar de pintar píxeles que nadie va a ver":
- Elimina fondos redundantes. El culpable más común es un color de fondo fijado en un contenedor raíz, luego otra vez en cada contenedor hijo, luego otra vez en cada fila de una lista —cuando solo el más externo (o ninguno, si el fondo de la ventana ya lo provee) es visible alguna vez.
- Aplana la jerarquía de vistas. Menos contenedores anidados con fondo individual significa menos rellenos de área completa apilados unos sobre otros. Por esto también
ConstraintLayout(Android) o un árbol de vistas de SwiftUI más plano tiende a rendir mejor que el anidamiento profundo incluso antes de entrar en el tema del overdraw —menos pasadas de layout y menos pasadas de dibujo mejoran a la vez. - Usa
clipRect/clipping y ventanas opacas donde puedas. Si una vista está garantizada a estar completamente cubierta, puedes indicarle al renderer que se salte su dibujo (View.setWillNotDrawen Android, o recortar unonDrawpersonalizado para pintar solo la región visible). - Evita translucidez innecesaria. El alpha blending es inherentemente más caro que un relleno opaco porque la GPU tiene que componer con lo que hay debajo en lugar de simplemente sobrescribirlo. Un scrim translúcido bajo un diálogo está bien; una cadena de cinco tarjetas translúcidas apiladas una sobre otra no lo está.
- Prefiere un único asset o color de fondo aplanado en lugar de apilar drawables —un nine-patch con una sombra incorporada, en vez de una vista de sombra más una vista de tarjeta más una vista de fondo, todas apiladas en vivo.
El punto más profundo para una entrevista: el overdraw es un problema de fill-rate, distinto del costo de layout/measure o del jank causado por trabajo pesado en el hilo principal. Una respuesta senior distingue esto —una pantalla puede tener una jerarquía de vistas barata de medir y ubicar, y aun así estar limitada por la GPU puramente por pintados apilados y mayormente ocultos—. Nombrar esa distinción, y saber qué herramienta diagnostica qué, es lo que separa "he oído hablar del overdraw" de "lo he arreglado de verdad en una app en producción".