Principales Razones por las que tu Aplicación Angular esta Lenta

Angular JS

Si sientes que tu aplicación Angular esta corriendo de manera lenta y quieres que tenga un mejor rendimiento, puede que no te hayas percatado de algunos aspectos que hacen que una aplicación corra de manera optima, Angular por defecto es un Framework rápido y de alto rendimiento y no deberíamos tener muchos problemas con el, pero en este Post te voy a compartir algunos detalles que pueden que estén haciendo que tu aplicación vaya lenta.

Existen muchos consejos y recursos populares para mejorar el rendimiento de una aplicación creada con Angular, la mayoría de consejos son buenos y válidos, pero a menudo no se habla mucho sobre los problemas que originan el bajo rendimiento de la aplicación.

A continuación te voy a compartir algunas de las razones más importantes por las que las aplicaciones creadas con Angular, se vuelven lentas, estas razones pueden servir para diferentes Frameworks como React JS, Vue JS, etc.

Micro Optimizaciones

Este es un tema muy incomprendido entre los Desarrolladores, muchas veces se tiene que lidiar con problemas de rendimiento en donde el código puede ser el causante de los problemas, estos suele suceder cuando se llevan a cabo tareas de micro optimizaciones, a continuación un par de situaciones en donde los Desarrolladores suelen tomar esta decisión:

  • “Estamos usando demasiado reduce, map and filter, ! reemplacémoslos todos por bucles ! “
  • “! Usemos un diccionario para acceder más rápido a los datos !”

Las situaciones anteriores son muy comunes y pueden haber otros casos similares, lo primero que los Desarrolladores hacen cuando están intentando encontrar la razón por la cual están experimentando un bajo rendimiento en su aplicación, es una depuración en cada llamado a una determinada función:

  • “¿ Cuanto se tardó la aplicación en encontrar un registro en la lista (de quizás 800 artículos) ?”
  • ¿ Cuanto tiempo lleva ordenar o filtrar los 800 registros ?

En algunos casos estas situaciones no son muy relevantes, esto no quiere decir que no sea importante considerarlas. Puede cuestionarse otros 2 posibles problemas:

  • ¿ Cuanto renderiza realmente la aplicación ?
  • ¿ Con que frecuencia el Framework vuelve a renderizar los componentes ?

Podemos ver que aunque se sigan las mejores prácticas, a veces no son suficientes para evitar un rendimiento lento de la aplicación, siempre hay cosas por mejorar.

La mayoría de veces no se debe al Framework que estamos utilizando, sino a la arquitectura de nuestro código.

La Aplicación se procesa con demasiada frecuencia

Este problema es muy común, la aplicación vuelve a procesar componentes innecesariamente, haciendo que la aplicación sea más lenta de lo normal, esto es a veces difícil de resolver, pero obviamente fácil de causar.

Detección de cambio

Se puede establecer la detección de cambio (ChangeDetectionStrategy) en OnPush, es ta debería ser una decisión casi obligatoria si la aplicación sufre de un rendimiento lento o si se desea evitar que ocurra en el futuro.

Al configurar los componentes de la aplicación, para que se actualicen solo al momento, evita que se vuelvan a generar componentes que no necesitan ser analizados. Es sencillo y su uso se simplifica enormemente cuando se utilizan Observables y AsyncPipe.

Async Pipe

Incluso si se utiliza OnPush y AsyncPipe en las plantillas, se puede renderizar  elementos que no se necesitan.

Evitar que los Observables se emitan, es una buena forma de evitar que un componente se vuelve a renderizar, podemos usar operadores como filter y distincUntilChanged para omitir re-renderizaciones por completo.

Otro problema que suele suceder al usar Observables y AsyncPipe, es cuando se seleccionan registros o datos sin usar selectores, cuando se usan selectores, solo recibimos actualizaciones del segmento de estado afectado.

Si seleccionamos todo el objeto de un árbol de estado de Redux (state tree), los selectores emitirán cada vez que cambie el árbol y como resultado terminaremos activando actualizaciones en componentes que prácticamente no se ven afectados.

Actualizaciones de alta frecuencia

Este caso no es un problema muy común en Angular, probablemente se deba a la dependencia Zone.js la cual detecta cambios mágicamente en el código de una aplicación.

Zone.js detecta todos los cambios realizados en el código, esto significa que si la aplicación esta transmitiendo eventos a una velocidad rápida mediante Websocket o eventos del DOM. por cada evento realizado, Zone activará una detección de cambio.

Para evitar esto, no es necesario eliminar la dependencia Zone.js, para esto podemos realizar los siguientes pasos:

  • Podemos separar los componentes afectados, luego actualizarlos manualmente cuando las actualizaciones sean notificadas.
  • Podemos hacer uso del callback ngZone.runOutsideAngular para ejecutar la respuesta de una llamada fuera de la detección de cambios (ChangeDetectionStrategy) de Angular.
  • Un último recurso es excluir el evento determinado detectado por Zone.js

Es importante hacer uso de las herramientas que angular nos ofrece en su documentación.

Tu Aplicación renderiza mucho elementos no optimizados

No importa que tal rápido sea Angular o el framework que estemos usando, si este esta procesando miles de componentes complejos a la vez, el navegador eventualmente mostrará cierta cantidad de retraso al cargar un proyecto.

Si tienes una PC con buenos recursos puede funcionar la aplicación rápida, si es es el caso de recursos de PC, pero hay otros usuarios que tienen PCs con pocos recursos, son las que sufrirán más para cargar un proyecto, debes pensar que no todos los usuarios cuentan con una máquina poderosa.

Debemos considerar que los componentes representan muchos elementos y deben estar optimizados de una manera particular, podemos resolver esto de las siguientes maneras:

Keying

Esta es una técnica simple y talvez muy conocida, se utiliza mucho en la mayoría de paquetes, librerías o dependencias. Este concepto es simple, asignamos una clave a cada elemento de una lista y la librería la volverá a renderizar solo si la clave ha cambiado.

Esto funciona muy bien al agregar y eliminar elementos o cuando la cantidad de elementos que cambian son ilimitados, pero aún así no resuelve algún problema de rendimiento si procesamos una gran cantidad de elementos a la vez, por ejemplo al renderizar una lista con muchos elementos.

Virtual Scrolling

Este solo representa lo que el usuario quiere ver, si bien esto no tiene implicaciones de accesibilidad/usabilidad a tomar en cuenta, es uno de los mejores métodos para mejorar el rendimiento de la aplicación y evita que la página se congele durante un periodo de tiempo irrazonable.

Async Rendering (Renderizado asíncrono)

Esta técnica ya tiene sus años y preferiría usar Virtual Scrolling, pero aún así puede ser mejor renderizar 1000 elementos a la vez y es muy fácil de implementar sin tener que escribir mucho código.

El concepto es el siguiente: comienza a representar un número limitado de elementos, por ejemplo de 50 de 500 elementos, luego programa una representación posterior con los siguientes 50 elementos usando el método setTimeout(0) hasta que se muestren todos los elementos. Esta es una técnica muy simple, por lo que los resultados también son simples, y el navegador no se atascará mucho tiempo cuando procesa los elementos.

Lazy Rendering

No todo tiene que ser renderizado de inmediato, a veces simplemente podemos renderizar un componente cuando el usuario necesita interactuar con el.

Podemos crear una instancia del componente cuando el usuario lo necesite, por ejemplo cuando el usuario se desplace o haga clic en él, con esto casi todos los problemas de rendimiento desaparecerán y la aplicación cargara de manera optima.

Lazy Listeners

Esto esta directamente relacionado con los puntos anteriores, suscribirse y llevar acabo demasiados eventos puede ser bastante delicado. Evitar que se lleven acabo demasiados eventos en una aplicación, lo podemos manejar de diferentes maneras:

  • Si tienes una lista muy grande de elementos en el DOM, asegúrate de llevar acabo eventos con solo los elementos que están visibles en la interface.
  • En algunas ocasiones podemos crear un solo evento global desde un Servicio, en lugar de crear un evento en cada Directiva o Componente.

Algún código es lento

Si analizaste y encontraste que tu aplicación no ejecuta procesos con demasiada frecuencia, entonces puede ser que tu código vaya bastante lento. Esto probablemente se deba a algunos scripts pesados y no están relacionados con DOM.

Por suerte existen al día de hoy herramientas para resolver este tipo de problemas:

  • Puedes usar WebWorkers, la Angular CLI también proporciona un comando para generar un WebWorker al instante. Con esta tecnología puedes ejecutar código paralelamente sin que afecte directamente el código de angular.
  • También puedes usar WebAssembly, existe la librería AssemblyScript que te puede ayudar con ello.

Si no te es suficiente con lo mencionado, puedes probar con micro optimizaciones y verificar cuanto puede mejorar el rendimiento en la ejecución de los procesos de la aplicación:

  • Utiliza una IterableDiffers personalizada.
  • Convierte todo a bucles, has uso de filter, reduce y map. Usa break y continue para reducir el número de iteraciones.

Estos son algunos consejos que te pueden ayudar a optimizar tu aplicación, si conoces algunos otros, puedes escribirlos en los comentarios.

Conclusión

En este Post hemos aprendido algunas maneras de darle un mejor rendimiento a una aplicación Angular, si los pones en práctica, lograrás dominarlos y encontrarás una forma de trabajar en la optimización de todos los proyectos que desarrolles con Angular.

Optimizar la carga de un proyecto es muy importante, así que manos a la obra.

Nota(s)

  • Algunos de los métodos y librerías pueden dejar de existir, ser modificados o continuar, esto no depende de mi, si no de los Desarrolladores que les dan soporte.
  • No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo. 

 

Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos. 

Newsletter

Suscríbete a Nuestro Boletín de Novedades:

(Luego de la suscripción no te va salir ningun mensaje. Solo revisa tu bandeja de Correo para confirmar tu suscripción)
* indicates required

Comentarios

avatar
  Subscribirse  
Notificar a