Saltar al contenido principal
Versión: 0.78

Perfilado

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

El perfilado es el proceso de analizar el rendimiento, el uso de recursos y el comportamiento de una aplicación para identificar posibles cuellos de botella o ineficiencias. Vale la pena utilizar herramientas de perfilado para garantizar que tu aplicación funcione sin problemas en diferentes dispositivos y condiciones.

Para iOS, Instruments es una herramienta invaluable, y en Android deberías aprender a usar el Profiler de Android Studio.

Pero primero, ¡asegúrate de que el modo de desarrollo esté DESACTIVADO!.

Perfilado del rendimiento de UI en Android con System Tracing

Android es compatible con más de 10 mil teléfonos diferentes y está generalizado para admitir renderizado por software: la arquitectura del framework y la necesidad de generalizar entre tantos dispositivos significa que obtienes menos optimizaciones automáticas que en iOS. Pero a veces hay aspectos que puedes mejorar, ¡y en muchas ocasiones ni siquiera es culpa del código nativo!

El primer paso para depurar estos tirones (jank) es responder dónde se invierte el tiempo durante cada fotograma de 16ms. Para ello usaremos el profiler de System Tracing integrado en Android Studio.

nota

La herramienta independiente systrace se ha eliminado de las platform-tools de Android. Utiliza el Profiler de Android Studio en su lugar, que ofrece la misma funcionalidad con una interfaz de usuario mejorada.

1. Recopilación de una traza

Primero, conecta mediante USB un dispositivo que presente los tirones que quieres investigar. Abre la carpeta android de tu proyecto en Android Studio, selecciona tu dispositivo en el panel superior derecho y ejecuta tu proyecto como perfilable.

Cuando tu app esté compilada como perfilable y se ejecute en el dispositivo, llévala justo antes de la navegación/animación que quieres analizar e inicia la tarea "Capturar actividades del sistema" en el panel del Profiler de Android Studio.

Una vez comience la recopilación, realiza la animación o interacción relevante. Luego presiona "Detener grabación". Ahora puedes analizar la traza directamente en Android Studio. Alternativamente, selecciónala en el panel "Grabaciones anteriores", pulsa "Exportar grabación" y ábrela en una herramienta como Perfetto.

2. Interpretación de la traza

Tras abrir la traza en Android Studio o Perfetto, verás algo similar a esto:

Ejemplo

Consejo

Usa las teclas WASD para desplazarte lateralmente y hacer zoom.

La interfaz exacta puede variar, pero las siguientes instrucciones aplican independientemente de la herramienta que uses.

Activar resaltado de VSync

Marca esta casilla en la esquina superior derecha para resaltar los límites de fotogramas de 16ms:

Activar resaltado de VSync

Deberías ver rayas de cebra como en la captura. Si no aparecen, prueba en otro dispositivo: se sabe que Samsung tiene problemas mostrando vsyncs, mientras que la serie Nexus suele ser más confiable.

3. Localiza tu proceso

Desplázate hasta ver (parte de) el nombre de tu paquete. En este caso, estaba analizando com.facebook.adsmanager, que aparece como book.adsmanager por los limitantes de longitud para nombres de hilos en el kernel.

En el lado izquierdo verás hilos que corresponden a las filas temporales de la derecha. Nos interesan especialmente estos hilos: el de UI (que lleva tu nombre de paquete o "UI Thread"), mqt_js y mqt_native_modules. Si usas Android 5+, también nos importa el Render Thread.

  • Hilo de UI (Interfaz de Usuario). Aquí ocurren las operaciones estándar de Android: medida, diseño y dibujo. El nombre del hilo a la derecha será el de tu paquete (en mi caso book.adsmanager) o "UI Thread". Los eventos que verás en este hilo se relacionarán con Choreographer, traversals y DispatchUI:

    Ejemplo del Hilo de UI

  • Hilo de JS (JavaScript). Aquí se ejecuta el código JavaScript. El nombre del hilo será mqt_js o <...> dependiendo del kernel del dispositivo. Para identificarlo sin nombre, busca elementos como JSCall, Bridge.executeJSCall, etc:

    Ejemplo del Hilo de JS

  • Hilo de Módulos Nativos. Aquí se ejecutan las llamadas a módulos nativos (ej. UIManager). El nombre será mqt_native_modules o <...>. Para identificarlo, busca NativeCall, callJavaModuleMethod u onBatchComplete:

    Ejemplo del Hilo de Módulos Nativos

  • Extra: Hilo de Renderizado. En Android L (5.0+) tendrás un hilo adicional que genera los comandos OpenGL para dibujar la UI. Su nombre será RenderThread o <...>. Identifícalo buscando DrawFrame o queueBuffer:

    Ejemplo del Hilo de Renderizado

Identificando el problema

Una animación fluida se vería así:

Animación Fluida

Cada cambio de color representa un fotograma. Para mostrarlo, todo el trabajo de UI debe completarse dentro de los 16ms. Observa que ningún hilo trabaja cerca del límite del fotograma. Así se logran 60 FPS.

Si hay tartamudeo, verás algo como esto:

Tartamudeo por JS

¡El hilo de JS ejecuta constantemente y cruza límites de fotograma! Esto causa bajos FPS. Aquí el problema está en JavaScript.

O podrías ver esto:

Tartamudeo por UI

Aquí los hilos UI y Renderizado cruzan límites de fotograma. Las vistas nativas requieren demasiado trabajo. En este caso el problema está en el renderizado nativo.

Esta información será crucial para tus siguientes pasos.

Solucionando problemas de JavaScript

Si identificaste un problema en JS, examina el código específico ejecutado. En el caso anterior, vemos RCTEventEmitter llamándose múltiples veces por fotograma. Vista ampliada:

Exceso de JS

¿Por qué tantas llamadas? ¿Son eventos distintos? Las respuestas dependerán de tu código. Generalmente conviene revisar shouldComponentUpdate.

Solucionando problemas de UI nativa

Si el problema está en la UI nativa, hay dos escenarios comunes:

  1. El renderizado por fotograma requiere demasiado trabajo en la GPU, o

  2. Estás construyendo nueva interfaz durante la animación/interacción (por ejemplo, cargando nuevo contenido durante un desplazamiento).

Demasiado trabajo en la GPU

En el primer escenario, verás un rastreo donde el hilo de interfaz y/o el Render Thread se ven así:

GPU sobrecargada

Observa el largo tiempo invertido en DrawFrame que cruza los límites del fotograma. Esto es tiempo esperando a que la GPU vacíe su búfer de comandos del fotograma anterior.

Para mitigar esto, deberías:

  • investigar el uso de renderToHardwareTextureAndroid para contenido complejo y estático que se esté animando/transformando (por ejemplo, las animaciones de deslizamiento/transparencia del Navigator)

  • asegurarte de que no estés usando needsOffscreenAlphaCompositing, que está desactivado por defecto, ya que en la mayoría de casos aumenta significativamente la carga por fotograma en la GPU.

Creando nuevas vistas en el hilo de interfaz

En el segundo escenario, verás algo más parecido a esto:

Creando vistas

Observa que primero el hilo de JS procesa un momento, luego ves trabajo en el hilo de módulos nativos, seguido de un recorrido costoso en el hilo de interfaz.

No existe una solución rápida a menos que puedas posponer la creación de nueva interfaz hasta después de la interacción, o simplificar la interfaz que estás creando. El equipo de React Native está trabajando en una solución a nivel de infraestructura que permitirá crear y configurar nueva interfaz fuera del hilo principal, manteniendo la fluidez de la interacción.

Identificando puntos críticos nativos de CPU

Si el problema parece estar en el lado nativo, puedes usar el perfilador de puntos críticos de CPU para obtener más detalles. Abre el panel Profiler de Android Studio y selecciona "Buscar puntos críticos de CPU (Grabación de métodos Java/Kotlin)".

Selecciona la grabación Java/Kotlin

Asegúrate de seleccionar "Buscar puntos críticos de CPU (Grabación Java/Kotlin)" en lugar de "Buscar puntos críticos de CPU (Muestreo de pila)". Tienen iconos similares pero funciones diferentes.

Realiza las interacciones y presiona "Detener grabación". La grabación consume muchos recursos, así que mantén la interacción breve. Puedes inspeccionar el rastreo resultante en Android Studio o exportarlo y abrirlo en una herramienta online como Firefox Profiler.

A diferencia del System Trace, el perfilado de puntos críticos de CPU es lento y no proporcionará mediciones precisas. Sin embargo, te dará una idea de qué métodos nativos se están llamando y dónde se gasta el tiempo proporcionalmente en cada fotograma.