Optimizar Aplicaciones en Angular Pt.2

¿Cómo mejorar el rendimiento de mi aplicación en angular?

Javier Ruiz Vázquez
Comunidad JavaScript
5 min readApr 29, 2019

--

Optimizing Angular Apps

AOT (Ahead of Time)

En el otro lado de la compilación JIT (Just In Time) de Angular, donde la compilación se realiza en el navegador, es decir durante el runtime del navegador angular se encarga de compilar las vistas, tenemos la compilación AOT, JIT tiene dos vertientes:

  1. El proceso de compilación debe correr antes de que tu aplicación sea utilizada por el usuario y esto incrementa el tiempo que toma tu sitio en ser cargado.
  2. Tenemos que enviar el compilador de angular con tu aplicación y esto resulta en un módulo muy grande que se desplegará con ella.

Lo que hace la compilación AOT es compilar gran parte de tu aplicación durante el proceso de compilación, un pre-compilado, lo que reduce la carga del navegador para realizar esta acción, esto lo aprovechamos para poder hacer que nuestras vistas carguen mas rápido.

Para utilizar esta compilación en producción solo tenemos que agregar un flag a nuestro ng build:

Si el flag prod está presente, no es necesario añadirla, por default en este modo AOT esta presente.

Angular Zone

Como parte de Angular en su versión 2, se introdujo una librería llamada zone.js que es un contexto de ejecución para nuestra aplicación, anteriormente en Angular 1.x, ocurría que nuestras vista no se actualizaban cuando debería hacerlo, esto pasaba por que teníamos funciones asíncronas de las cuales al cambiar algún estado, nuestra aplicación no se enteraba.

Zone nos ayuda a mejorar el Profiling de la aplicación evitando que esto suceda o bien suceda en otro contexto, Angular lo utiliza en la detección de cambios, pero ¿Cuándo suceden estos cambios?

  • Eventsclick, change, input, submit, etc
  • XMLHttpRequests — Cuando interactuamos con información de un servicio
  • TimerssetTimeout(), setInterval()

Todos estos eventos son asíncronos.

Hay ocasiones en que necesitamos ejecutar una función en donde no necesitamos o sabemos que no tendrá algún efecto en los datos, por lo que no queremos que angular se entere y ejecute su detección de cambios.

Digamos que tenemos un intervalo de tiempo que imprime el tiempo cada segundo por ejemplo:

Esto lanzará la detección de cambios cada segundo que se ejecute el intervalo. Por lo que para evitarlo tendríamos que ver el siguiente ejemplo:

NgZone

NgZone es una ramificación que extiende de su API y agrega una funcionalidad a su contexto de ejecución. Los conjuntos de eventos personalizados a los que podemos suscribirnos son:

  • onTurnStart() — Notifica a los suscriptores justo antes de que comience el evento. Emite un evento una vez por tarea del navegador. Manejado por Angular.
  • onTurnDone() — Notifica a los suscriptores inmediatamente después de que la zona de Angular haya terminado de procesar el turno actual y las micro tareas programadas desde ese turno.
  • onEventDone() — Notifica a los suscriptores inmediatamente después de la última llamada.
  • onTurnDone() — Antes de finalizar el evento de la VM. Útil para probar para validar el estado de la aplicación.

Async Pipe vs Subscriptions

Cuando trabajamos con RxJs, exponemos nuestro estado de la aplicación en forma de streams utilizando Observables a los cuales tenemos que suscribirnos, lo cual puede hacernos caer en un memory leak, ya que tenemos que cancelar esas suscripciones cuando ya no son necesarias, un ejemplo:

Cancelando suscripción utilizando Subscription
Cancelando suscripción utilizando Subject
Cancelando múltiples suscripciones

Como desventaja tenemos que no funciona con la estrategia de detección de cambios OnPush de angular, y que tenemos que recordar cancelar la suscripción en el ciclo de vida del componente OnDestroy, para hacer que funcione en ChangeDetectionStrategy OnPush tendríamos que agregar a nuestro constructor private cd: ChangeDetectorRef y en nuestro subscription this.cd.markForCheck() para indicarle a Angular que hay cambios.

Angular nos provee también de un pipe llamado Async que nos ayuda con esta tarea la cual si funciona con ChangeDetectionStrategy OnPush y cancela automáticamente la suscripción.

Utilizando Async Pipe

Como desventaja tenemos que las propiedades del stream de datos no son accesibles dentro de la clase de nuestro componente y por lo cual tendríamos que pasar estos datos por otro método dentro de nuestro template, el uso de async es bueno cuando solo tenemos colecciones directas, de otro modo incurriríamos en el ejemplo de la parte 1 de cálculos en la vista.

Google Closure Compiler

Este es un compilador utilizado por Google para sus productos, lo que te ayuda a tener un build más pequeño utilizando Webpack y Uglify para realizar una minificación más agresiva. Angular no lo soporta actualmente pero se puede ver su integración en este POST.

SSR (Server Side Render)

Angular permite una opción para poder servir tu aplicación del lado del servidor llamada Angular Universal.

Normalmente ejecutamos nuestra aplicación del lado del navegador, renderizando nuestras páginas según las acciones del usuario, lo que nos permite Angular Universal es poder renderizar nuestro contenido desde el servidor como si fuera una aplicación hecha con cualquier lenguaje de este lado (NodeJs, PHP, Go, Ruby, Python, etc.), generando páginas estáticas que luego se muestran al cliente, haciendo que la aplicación se procese más rápido y nos ayuda a que el usuario vea una vista antes de que pueda interactuar con ella, esto ayuda al SEO y el aprovechamiento de los metadatos.

Razones para utilizar SSR:

  1. Optimización para buscadores (SEO — Search Engine Optimization): Los buscadores y redes sociales confían en los rastreadores web para indexar el contenido de tu aplicación.
  2. Mejora el rendimiento en dispositivos móviles: Algunos dispositivos no admiten Javascript o lo ejecutan de mala manera que es perjudicial para la experiencia de usuario, para estos casos es probable que se necesite una versión procesada de la aplicación desde el servidor sin Javascript.
  3. Muestra la primera página rápidamente (FCP — First-Contentful Paint): Mostrar la primera página de la aplicación en pocos segundos es crítico para el usuario ya que si demora mucho tiempo en cargar es probable que el usuario no se quede en tu sitio.

Integrando Angular Universal en un proyecto con CLI:

Para más información acerca de esta funcionalidad les dejo la documentación oficial de Angular

PWA (Progressive Web App)

PWA hace que tu aplicación cargue mucho más rápido, te da la capacidad de trabajar Offline y una interacción y experiencia de usuario muy cercana a una aplicación nativa, lo que mejora el rendimiento percibido por el usuario, dependiendo del proyecto podrás elegir si utilizar esta funcionalidad o no.

Una PWA utiliza el caché del navegador local para permitir esta funcionalidad de experiencia de una aplicación nativa, brindando la mayoría de la funcionalidad aunque te encuentres offline, de igual manera pueder servir recursos locales para tu aplicación y después enviarlos cuando encuentre conexión a un Server para realizar determinada acción como por ejemplo un guardado en base de datos.

Para conocer más acerca de PWA consulta la documentación de google developers.

Follow me on Medium or Twitter!, Si te gusto dale clap a la manita para saber que estoy haciendo las cosas bien, y déjame tus comentarios!!!

--

--