Micro optimizaciones - haroldVirguez/VINYLS-MOBILE GitHub Wiki

📘 Micro-Optimizaciones y Análisis de Performance

En esta iteración se incorporaron ajustes orientados a mejorar la fluidez y la experiencia visual dentro de la aplicación.


🛠️ Micro optimizaciones — Análisis Android Lint: Performance

Fecha: 2025-10-15

Contexto

Se detectaron advertencias de rendimiento en el proyecto desde Android Lint. Capturas muestran dos estados: un listado general con 22 warnings.

Resumen rápido:

  • Total performance warnings: 22
    • Invalidating All RecyclerView Data: 2
    • Overdraw (pintar regiones más de una vez): 7
    • Unnecessary parent layout: 3
    • Unused resources: 10

Reproducción del análisis

  1. Ejecutar inspección en Android Studio: Analyze > Inspect Code.
  2. O con Gradle:
    ./gradlew lint
    
  3. Revisar el panel Android Lint: Performance.

Decisiones tomadas para resolver Warnings

  • Eliminación de fondos redundantes para evitar múltiples capas opacas.
  • Reducción de contenedores innecesarios para mejorar la jerarquía de vistas.
  • Eliminación de recursos no utilizados (unused resources).

Segunda ejecución del análisis

Una vez implementadas estas mejoras se procede a realizar una nueva ejecución, donde se identifican 2 warnings pendientes:

  • AlbumsAdapter.kt — 1 warning
  • MusiciansAdapter.kt — 1 warning

El warning “Invalidating All RecyclerView Data” aparece cuando el adaptador invalida toda la lista, ya sea usando notifyDataSetChanged() o reasignando una nueva lista sin aplicar un mecanismo de diferencias. Esta operación fuerza un rebind completo de todos los ítems, elimina animaciones y genera trabajo adicional para la CPU y la GPU.
En listas grandes o con desplazamientos frecuentes, esto se refleja en jank, pérdida de fluidez y un mayor consumo de recursos.

Cuando se invalida la lista completa, el sistema debe ejecutar múltiples ciclos de layout, measure y draw, e incluso puede aumentar el overdraw si existen vistas superpuestas. Esto se considera un antipatrón en RecyclerView, el cual está diseñado para manejar actualizaciones incrementales de manera eficiente.

🔧 1. Solución implementada

  • Refactorización de AlbumsAdapter y MusiciansAdapter para utilizar ListAdapter junto con DiffUtil, permitiendo actualizaciones más eficientes de los elementos.
  • Optimización del proceso de bind() en los adapters para reducir trabajo innecesario por ítem.
  • Eliminación de dimensiones y otros recursos que no estaban siendo utilizados.

🔄 2. Migración a Glide para la carga de imágenes

Se reemplazaron métodos previos de carga de imágenes por Glide, lo que permitió:

  • Manejo más eficiente de memoria.
  • Carga asíncrona sin bloquear el UI thread.
  • Mejor rendimiento al trabajar con listas extensas (RecyclerView).

💾 3. Implementación de Glide con caché (disk + memory)

Se configuraron estrategias de caché para reducir descargas repetidas y acelerar el renderizado de las pantallas.

Beneficios principales:

  • Menor tráfico de red.
  • Imágenes reutilizadas entre navegaciones.
  • Scroll más fluido y estable.

Ejemplo de configuración de caché:

diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)

🖼️ 4. Uso de placeholder y fallback en la carga de imágenes

Para la pantalla de detalle del álbum se añadieron imágenes temporales y de respaldo usando Glide, con el fin de mejorar la experiencia visual mientras se carga el cover o cuando ocurre un error.

Glide.with(requireContext())
    .load(album.cover.toUri().buildUpon().scheme("https").build())
    .placeholder(R.drawable.placeholder_img)
    .error(R.drawable.ic_broken_image)
    .diskCacheStrategy(DiskCacheStrategy.ALL)
    .into(binding.imgAlbumCover)

✅ Resultados

  • Se evita mostrar espacios vacíos al cargar el cover del álbum.
  • El usuario siempre ve una imagen válida incluso si la URL falla o el recurso no existe.

⚡ 5. Corutinas + Retrofit (ya presentes desde SP1)

Desde el SP1 el proyecto ya contaba con:

  • Llamadas de red suspend no bloqueantes mediante corutinas.
  • Integración con Retrofit para manejar peticiones de forma eficiente.
  • Menor carga sobre el hilo principal al ejecutar operaciones de red.

Estas optimizaciones ya estaban implementadas; en esta etapa se reforzó principalmente el desempeño en la capa de presentación (UI), especialmente en el manejo de imágenes.


📌 Resumen general

Las mejoras combinadas aportan:

  • Mayor rendimiento visual.
  • Reducción de tiempos de carga percibidos.
  • Menor consumo de red y recursos.
  • Scroll más fluido y estable.
  • Árbol de vistas más liviano y eficiente.
  • Adaptadores optimizados con actualizaciones incrementales mediante DiffUtil.

Estas mejoras complementan lo logrado en SP1 y preparan la aplicación para futuras iteraciones de forma más robusta.