Estrategias de precarga de rutas en Angular

Precarga las rutas con anticipación para acelerar las rutas la navegación.

La división de código a nivel de ruta puede ayudarte a reducir el tiempo de carga inicial de una aplicación, ya que retrasa el código JavaScript asociado con rutas que no son necesarias en un principio. De esta manera, el router de Angular espera hasta que un usuario navegue a una ruta determinada antes de activar una solicitud de red para descargar el JavaScript asociado.

Si bien esta técnica es ideal para la carga inicial de la página, puede ralentizar la navegación, según la latencia de red y el ancho de banda. Una forma de abordar este problema es la precarga de rutas. Con la precarga, cuando el usuario se encuentra en una ruta determinada, puedes descargar y almacenar en caché JavaScript asociado con las rutas que probablemente se necesiten a continuación. El router Angular proporciona esta funcionalidad desde el primer momento.

En esta publicación, aprenderás a acelerar la navegación cuando uses la división de código a nivel de la ruta aprovechando la precarga de JavaScript en Angular.

Estrategias de precarga de rutas en Angular

El router de Angular proporciona una propiedad de configuración llamada preloadingStrategy, que define la lógica para la precarga y el procesamiento de los módulos de Angular de carga diferida. Abordaremos dos estrategias posibles:

  • PreloadAllModules, que precarga todas las rutas de carga diferida, como su nombre lo indica
  • QuicklinkStrategy, que precarga solo las rutas asociadas con los vínculos de la página actual

El resto de esta publicación hace referencia a una app de ejemplo de Angular. Puedes encontrar el código fuente en GitHub.

Usa la estrategia de PreloadAllModules

La app de ejemplo tiene varias rutas de carga diferida. Para precargarlos todos con la estrategia PreloadAllModules, que está integrada en Angular, especifícala como el valor de la propiedad preloadingStrategy en la configuración del router:

import { RouterModule, PreloadAllModules } from '@angular/router';
// …

RouterModule.forRoot([
  …
], {
  preloadingStrategy: PreloadAllModules
})
// …

Ahora, procesa la aplicación y observa el panel Network en las Herramientas para desarrolladores de Chrome:

  1. Presiona `Control + Mayúsculas + J` (o `Command + Option + J` en Mac) para abrir Herramientas para desarrolladores.
  2. Haga clic en la pestaña Red.

Deberías ver que el router descargó nyan-nyan-module.js y about-about-module.js en segundo plano cuando abriste la aplicación:

La estrategia PreloadAllModules en acción

El router también registró las contraseñas de modo que, cuando navegues a una URL asociada con cualquiera de los módulos precargados, la transición sea instantánea.

PreloadAllModules es útil en muchos casos. Sin embargo, cuando tienes decenas de módulos, su precarga agresiva realmente puede aumentar el uso de la red. Además, como el router debe registrar las rutas en todos los módulos precargados, esto puede generar cálculos intensivos en el subproceso de IU y provocar una experiencia del usuario lenta.

La biblioteca de Quicklink brinda una mejor estrategia para apps más grandes. Usa la API de IntersectionObserver para precargar solo los módulos asociados con vínculos que están visibles en la página.

Puedes agregar un vínculo rápido a una app de Angular con el paquete ngx-quicklink. Primero, instala el paquete de npm:

npm install --save ngx-quicklink

Una vez que esté disponible en tu proyecto, podrás usar QuicklinkStrategy si especificas el preloadingStrategy del router y, luego, importas el QuicklinkModule:

import {QuicklinkStrategy, QuicklinkModule} from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    …
    QuicklinkModule,
    RouterModule.forRoot([…], {
      preloadingStrategy: QuicklinkStrategy
    })
  ],
  …
})
export class AppModule {}

Ahora, cuando vuelvas a abrir la aplicación, notarás que el router solo precarga nyan-nyan-module.js, ya que el botón en el centro de la página tiene un vínculo de router. Y cuando abras el panel de navegación lateral, verás que el router precarga el botón "Acerca de" ruta:

Una demostración de la estrategia de precarga de vínculo rápido.

El ejemplo anterior funcionará para una aplicación básica, pero si esta contiene varios módulos de carga diferida, deberás importar QuicklinkModule a un módulo compartido, exportarlo y, luego, importar el módulo compartido a tus módulos de carga diferida.

Primero, importa el archivo QuicklinkModule de ngx-quicklink al módulo compartido y expórtalo:

import { QuicklinkModule } from 'ngx-quicklink';
…

@NgModule({
  …
  imports: [
    QuicklinkModule
  ],
  exports: [
    QuicklinkModule
  ],
  …
})
export class SharedModule {}

Luego, importa tu SharedModule a todos los módulos de carga diferida:

import { SharedModule } from '@app/shared/shared.module';
…

@NgModule({
  …
  imports: [
      SharedModule
  ],
  …
});

Quicklinks ahora estará disponible en tus módulos de carga diferida.

Más allá de la precarga básica

Si bien la precarga selectiva a través de vínculos rápidos puede acelerar significativamente la navegación, puedes hacer que tu estrategia de precarga de red sea aún más eficiente en la red usando la precarga predictiva, que es implementada por Guess.js. Mediante el análisis de un informe de Google Analytics o de otro proveedor de herramientas de análisis, Guess.js puede predecir el recorrido de navegación de un usuario y precargar solo los bloques de JavaScript que probablemente se necesiten a continuación.

Puedes aprender a usar Guess.js con Angular en esta página del sitio de Guess.js.

Conclusión

Para acelerar la navegación cuando usas la división de código a nivel de ruta, haz lo siguiente:

  1. Elige la estrategia de precarga adecuada según el tamaño de tu aplicación:
    • Las aplicaciones con pocos módulos pueden usar la estrategia PreloadAllModules integrada de Angular.
    • Las aplicaciones con muchos módulos deben usar una estrategia de precarga personalizada, como el vínculo rápido de Angular, o la precarga predictiva, como se implementa en Guess.js.
  2. Para configurar la estrategia de precarga, configura la propiedad preloadStrategy del router de Angular.