Reducción del 60% en el tamaño de la aplicación React Native en unos pocos pasos simples

Yo trabajo en Mutual . Ella trabaja en Brasil, en el campo de la igualdad de crédito. Ayudamos a prestatarios y prestamistas a conectarse entre sí. Los primeros buscan buenas apuestas, mientras que los segundos buscan ingresos que excedan lo que el mercado puede ofrecerles. Nuestro producto es utilizado por una amplia gama de usuarios, trabajamos en un país grande. Como resultado, nuestras aplicaciones React Native basadas en iOS y Android se descargan a dispositivos muy diferentes.



Cabe señalar que la mayoría de nuestros usuarios instalan aplicaciones en dispositivos económicos. Podemos sacar tales conclusiones utilizando los datos de la biblioteca de clase de año de dispositivo de Facebook.. Esta biblioteca, después de haber recibido información sobre el modelo del dispositivo, informa en qué año este dispositivo se consideraría un teléfono insignia exclusivo. Por ejemplo, el teléfono más popular entre nuestros usuarios es el Samsung Galaxy A10. Este teléfono, aunque fue lanzado en 2019, podría considerarse el buque insignia solo en 2013. Analizando los datos en los dispositivos de los usuarios, podemos decir que el 85% de estos dispositivos podrían reconocerse como dispositivos de gama alta solo en 2015 o antes. Debido a esto, tenemos requisitos especiales para optimizar nuestra aplicación móvil. El objetivo de la optimización es que incluso los usuarios con dispositivos débiles puedan usar cómodamente nuestra aplicación.


Porcentaje de dispositivos que podrían ser reconocidos como emblemáticos en un año en particular

En este sentido, prestamos mucha atención al tamaño de la aplicación. En el caso de su versión de Android, tenía 26.8 MB. Aunque este no es un tamaño tan grande, definitivamente es más que el tamaño medio de las aplicaciones de nuestros usuarios. Esta cifra, según la consola Google Play, es de 16.3 MB. El tamaño de la aplicación puede ser un factor decisivo para los usuarios con planes tarifarios limitados, o para aquellos con dispositivos con poca memoria, lo que obliga a los usuarios a elegir cuidadosamente las aplicaciones que habrán instalado. Como resultado, algunas aplicaciones tienen que ser desinstaladas. Esto es especialmente importante en el caso de la aplicación Mutua, ya que los prestatarios pagan cuotas mensuales a través de esta aplicación. Cuando el prestatario desinstala nuestra aplicación, las posibilidades de que realice el pago a tiempo se reducen considerablemente.Y esto afecta directamente las ganancias de los inversores que usan nuestra plataforma.


El tamaño de la aplicación Mutual es mucho mayor que el tamaño medio de las

aplicaciones de nuestros usuarios . El tamaño de la aplicación no solo afecta el nivel de desinstalaciones. El tamaño también afecta la tasa de conversión de la configuración de la aplicación. Aquí hay un buen artículo sobre esto escrito por el equipo de Google Play. Este artículo analiza la importancia del tamaño de la aplicación. En particular, dice que cada 6 MB adicionales del tamaño del archivo APK reduce la tasa de conversión de las instalaciones en un 1%.

También hablan sobre el hecho de que en los países en desarrollo donde los dispositivos de presupuesto son la norma, este efecto es aún más fuerte. Es decir, reducir el tamaño del archivo APK en 10 MB en los mercados emergentes corresponde a un aumento en la tasa de conversión de las instalaciones en aproximadamente un 2,5%.


Aumentar la tasa de conversión de las instalaciones por cada 10 Mb de reducción del tamaño del archivo APK en diferentes países (según los datos internos de Google)

Nos motivó mucho cómo la reducción del tamaño de la aplicación puede afectar el nivel de desinstalaciones y la tasa de conversión de la configuración de la aplicación. Como resultado, nos pusimos a trabajar para reducir al máximo el tamaño de la aplicación, teniendo en cuenta su conveniencia para los usuarios. El primer paso en este proyecto fue analizar las recomendaciones oficiales deGoogle para los desarrolladores de Android.

Paquete de aplicaciones de Android


Al leer las recomendaciones, aprendimos que la forma más fácil de reducir el tamaño de una aplicación es utilizar un nuevo método de distribución de aplicaciones llamado Paquete de aplicaciones de Android (AAB). Hasta ese momento, distribuimos la aplicación, recolectamos el viejo archivo Android Package (APK), que se puede ejecutar en la mayoría de los dispositivos Android, y lo cargamos en la Consola de Google Play. Pero el paquete AAB contiene solo código compilado y recursos. Como resultado, cuando se descarga, Google es responsable de generar archivos APK optimizados para varios tipos de dispositivos, teniendo en cuenta sus especificaciones y arquitectura de CPU.

Resulta que al hacer un simple cambio en el proceso de construcción del proyecto, ¿podemos obtener una reducción seria en el tamaño de la aplicación sin hacer más esfuerzo? ¡Esto es demasiado bueno para la verdad!

Después de leer la documentación, simplemente cambiamos el script de compilación React Native Gradle para que se assembleReleaseejecute en lugar del actual bundleRelease. Eso es todo lo que necesitábamos para crear el archivo AAB. Después de hacer algunas modificaciones más a la supplyconfiguración de Fastlane con respecto a la carga automática de materiales directamente a Play Store, cambiamos a AAB y apareció una nueva versión de nuestra aplicación en Google Play Console.

Este cambio solo ha llevado a una reducción en el tamaño de los archivos APK transferidos a los dispositivos de los usuarios. La disminución varió de 9.1 a 12.4 Mb. Al final resultó que, el uso de Android App Bundle es una técnica efectiva que, de hecho, le permite reducir el tamaño de la aplicación.


El antiguo archivo APK y el nuevo paquete AAB, cuyo uso lleva al hecho de que el tamaño de la aplicación en diferentes dispositivos puede ser de 14.4 a 17.7 MB.

Verdadero, debe tener cuidado aquí. Si usa React Native con Hermes , es posible que deba actualizar su dependenciasoloader(consulte los detalles aquí ). De lo contrario, existe el riesgo de darle al usuario una aplicación que contendrá un error crítico. Tuvimos suerte, pudimos identificar este problema durante las pruebas de la versión alfa del proyecto. Pero el error podría pasar fácilmente a producción, ya que no aparece durante las pruebas locales o al compilar el archivo APK.

Optimización de recursos de aplicaciones con Android Size Analyzer


La siguiente sugerencia para optimizar las aplicaciones que encontramos en la documentación fue el uso de Android Size Analyzer . Esta es una herramienta de línea de comandos que analiza las aplicaciones de Android y busca formas de reducir su tamaño. Lanzamos esta herramienta usando un comando de la siguiente forma:

size-analyzer check-bundle [BUNDLE].aab

Como resultado, obtuvimos una lista de excelentes recursos de aplicaciones e imágenes que podemos optimizar. También nos recomendaron configurar ProGuard.


Informe del analizador de tamaño

▍ProGuard


ProGuard es una herramienta para comprimir, ofuscar y optimizar el código de bytes de Java. Todavía no hemos explorado la posibilidad de usar esta herramienta, ya que aprendimos que puede no ser compatible con algunas bibliotecas de Android. Como nos esforzamos por reducir el tamaño de nuestra aplicación lo más rápido posible, y para que esto sea lo más simple posible, decidimos dejar este método de optimización en el futuro.

▍ Grandes recursos de la aplicación


Ejecutándolo size-analyzernuevamente, con la clave -d, obtuvimos una lista de recursos de la aplicación, ordenados por su tamaño. Dado que esta herramienta no sabe nada acerca de cómo trabajan los usuarios con la aplicación, nos dio la oportunidad de decidir independientemente qué recursos deberían eliminarse y cuáles deberían cargarse dinámicamente en la aplicación.


Lista de recursos de aplicaciones grandes ordenados por tamaño

El primer y más grande recurso en esta lista fue el paquete React Native JavaScript. Ahora no podemos dividir este paquete y cargarlo dinámicamente. Pero luego lo pensaremos. Más abajo en la lista hay archivos de fuentes grandes (TTF) y archivos de imágenes (JPG y PNG).

▍ Imágenes innecesarias


Nos llamaron la atención de inmediato las enormes imágenes JPG utilizadas en Storybook . Utilizamos este sistema para desarrollar y probar componentes. Esto es 2 MB de basura que cayeron en la versión de producción del proyecto. ¡Vergonzoso error! Cuando sucede algo como esto, sentimos que hemos hecho una estupidez grave. Pero en el complejo mundo del desarrollo de software, todos cometen errores. Creo que si habla de sus errores públicamente, ayudará a otros desarrolladores a aprender de estos errores. Existe la posibilidad de que cometa los mismos errores si no analiza la estructura de recursos de la aplicación, cuyo tamaño aumenta gradualmente.

▍ Fuentes


Después de eliminar rápidamente las imágenes innecesarias, procedimos a analizar otros elementos de la lista de recursos. Estaba claro que había muchas fuentes incorporadas. Después de hablar de esto con nuestros diseñadores, nos dijeron que muchos componentes antiguos no difieren en el estricto cumplimiento de los manuales tipográficos. Por lo tanto, descubrimos qué componentes se pueden eliminar y en qué puede usar las fuentes actualizadas adecuadas. Gracias a esto, pudimos reducir la cantidad de fuentes utilizadas de seis a cuatro.

Otra cosa que notamos fue el gran tamaño de los propios archivos de fuentes. El tamaño de cada uno de ellos era de aproximadamente 670 Kb. Esto significó que cuatro fuentes en el paquete sin comprimir ocupan unos impresionantes 2.7 Mb. Pero, afortunadamente, hay una herramienta llamada FontForge que le permite analizar y modificar profundamente los archivos de fuentes. Con esta herramienta, pudimos descubrir que la razón principal del gran tamaño de los archivos de fuente son los caracteres cirílicos extendidos y los glifos innecesarios. Podríamos eliminar todo esto de manera segura, ya que la parte de texto de nuestra aplicación está completamente escrita en portugués. Gracias a este cambio, pudimos reducir el tamaño de los archivos de fuentes de 670 Kb a 70 Kb, en un 90%.


Ejemplos de algunos glifos incluidos en nuestras fuentes:

debido a que eliminamos las fuentes innecesarias y optimizamos las restantes, pudimos reducir el tamaño de la aplicación en 3.8 Mb. Esto condujo a una reducción agradable en el tamaño total del archivo APK en 2 MB.


Lista de fuentes y sus tamaños antes de la optimización.


Lista de fuentes y sus tamaños después de la optimización.

▍Optimización de imágenes


Después de analizar las imágenes que aún permanecían en la aplicación, notamos que algunas de ellas son bastante grandes. Procesamos varias de estas imágenes con la herramienta de optimización de gráficos TinyPNG y vimos una reducción significativa en el tamaño de estas imágenes. Después de eso, decidimos optimizar todas las imágenes JPG y PNG utilizadas en la aplicación. Eran 41 de ellos.


Imagen antes y después de la optimización

Esto nos dio la oportunidad de reducir el tamaño de las imágenes de 2.5 MB a 756 KB, es decir, en un 70%. Sin embargo, debido al hecho de que las imágenes no estaban optimizadas previamente, se comprimieron durante la creación del archivo APK final. Resultó que nuestra optimización condujo a una disminución en el tamaño de la aplicación descargada por el usuario en solo 500 Kb.

Después de eso, nos dimos cuenta de que ya habíamos agotado todas las posibilidades de optimización rápida. Continuar con la optimización de los recursos requeriría grandes esfuerzos o solo mejoras menores.

Reaccionar optimización de paquete de JavaScript nativo


Después de descubrir los recursos de la aplicación específicos para la plataforma Android, es hora de analizar el paquete de JavaScript. La optimización de paquetes puede considerarse una buena idea por tres razones. En primer lugar, reduce el tamaño del archivo APK terminado. En segundo lugar, esto lleva a un lanzamiento más rápido de la aplicación, ya que la máquina virtual JS tiene que procesar menos código. Finalmente, y lo más importante, acelera las actualizaciones de OTA que hacemos varias veces a la semana usando CodePush .

▍ Analizador de paquetes y optimización de código


Para tomar una decisión sobre cómo reducir el tamaño del paquete, primero, tenía que averiguar qué ocupaba más lugar en el paquete. Para hacer esto, utilizamos la excelente herramienta de código abierto react-native-bundle-visualizer . Después de analizar el proyecto con su ayuda, obtuvimos una visualización en la que cada carpeta y cada dependencia de la aplicación estaba presente, indicando los tamaños de las entidades correspondientes.


Instantánea de las bibliotecas y carpetas de la base de código de la interfaz de la aplicación Mutual con la indicación de los tamaños

Descubrimos que el tamaño total del paquete es de 5.49 Mb. El 57.8% de este volumen está representado por dependencias de la carpetanode_modules, el 27.5% - código de aplicación. Lo que queda, la herramienta utilizada por nosotros no pudo ser identificada. Durante el proceso de ensamblaje del paquete, el código no utilizado ya se eliminó, por lo que lo que vimos fue el código que realmente utiliza la aplicación. Pero, incluso considerando esto, en el paquete siempre puedes encontrar algo que se puede mejorar.

La mayor dependencia del proyecto esmath.js. Esta biblioteca, como su nombre lo indica, implementa muchas operaciones matemáticas. No tenemos una necesidad especial de esta biblioteca debido al hecho de que realizamos todos los cálculos importantes en el servidor, después de lo cual simplemente enviamos los resultados a la aplicación. Cuando miramos el código de la aplicación, resultó que la biblioteca se usa solo para realizar algunas operaciones simples. Probablemente fue utilizado por un desarrollador que trabajó en el código del servidor solo en virtud del hábito. Rápidamente extrajimos los métodos apropiados de la biblioteca y los incorporamos a nuestra base de código, eliminando por completo esta dependencia. Esto permitió reducir el tamaño del paquete a 4.64 Mb. ¡El rechazo de una sola biblioteca permitió reducir el tamaño del paquete en un 15,5%!

Como ya se mencionó, usamos Storybook para desarrollar y probar componentes. Es cierto que las capacidades correspondientes deberían estar disponibles solo en entornos locales e intermedios. Los usuarios finales no necesitan esto. Gracias a esto, utilizamos la variable ENVIRONMENTpara controlar la inclusión de la parte correspondiente de la aplicación. Aunque esto es adecuado para restringir el acceso, el agrupador no puede saber qué valor se escribe en esta variable. Debido a esta limitación, todo el código de Storybook cayó en el paquete de producción.

Para solucionar el problema, aislamos la importación de esta sección dentro de un solo archivo. Luego creamos dos versiones de este archivo: una que incluye Storybook y otra que es para producción, que contiene solo el diseño del componente. Para cambiar entre estos archivos al preparar la versión de producción del paquete, escribimos un script que se ejecuta antes de que se construya el proyecto y cambia un archivo a otro. Gracias a este método, pudimos eliminar completamente el código de Storybook de la versión de producción de la aplicación, eliminando tanto la dependencia node_modulescomo el código habitual con respecto a la configuración de las "historias" de Storybook.


Se actualizó la carpeta Storybook con dos versiones del archivo de índice.

Estos dos cambios redujeron el tamaño del paquete de 5,49 MB a 4,2 MB. Esto significa que, entre otras cosas, la aplicación se cargará más rápido y se actualizará más rápido.


El tamaño del paquete final fue de 4.2 MB.

Después de todas estas mejoras, volvimos a descargar la aplicación en Play Store. Ahora nos informaron que el tamaño del archivo APK terminado estará en el rango de 10.5 a 13.7 Mb. Esto, dado que la aplicación originalmente tenía un tamaño de 26.8 MB, ¡simplemente significa una reducción increíble en el tamaño del proyecto en aproximadamente un 60%! Entonces, como dijimos en un artículo del equipo de Google Play, podemos esperar que la tasa de conversión de las instalaciones aumente en un 3.75%.


Comparación de la versión APK original de la aplicación con la versión final de AAB, en la que se realizan todas las mejoras descritas anteriormente

Resumen


Nosotros, como programadores orientados a los negocios, sabemos que a veces las empresas, en aras de un desarrollo más rápido de un proyecto, pueden aumentar su deuda técnica. Esto es especialmente cierto para las nuevas empresas jóvenes como Mutual, que están tratando de encontrar su lugar en el mercado. Pero si no observa esta deuda, puede cometer errores molestos, como enviar 2 MB de imágenes de prueba a producción y el uso injustificado de una gran biblioteca. No se debe permitir que la deuda técnica se salga de control y cause problemas.

Además, a menudo sucede que los desarrolladores simplemente pierden las oportunidades disponibles para optimizar proyectos. Por lo tanto, a veces se recomienda analizar críticamente sus proyectos. Solo para verificar si perdió alguna oportunidad de optimizar rápidamente el tamaño, la velocidad o algún otro aspecto de la aplicación. Nos llevó solo dos días analizar la aplicación, planificar el trabajo y realizar mejoras en el proyecto, lo que nos permitió reducir el tamaño de la aplicación en un 60%. Es difícil encontrar algo más que pueda producir los mismos resultados en tan poco tiempo.

¿Cómo optimizas tus proyectos React Native?


All Articles