Estrategias de precarga de rutas en Angular

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

La división del código a nivel de ruta puede ayudarte a reducir el tiempo de carga inicial de una aplicación, ya que retrasa el JavaScript asociado con las rutas que no son necesarias inicialmente. 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 excelente para la carga inicial de la página, puede ralentizar la navegación, según la latencia de la red y el ancho de banda de los usuarios. 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 de Angular proporciona esta funcionalidad lista para usar.

En esta publicación, aprenderás a acelerar la navegación cuando uses la división de código a nivel de 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 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 vínculos en 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ícalo como el valor de la propiedad preloadingStrategy en la configuración del router:

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

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

Ahora entrega la aplicación y observa el panel Red en las Herramientas para desarrolladores de Chrome:

  1. Presiona "Control + Mayús + J" (o bien "Comando + Opción + 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 abres la aplicación:

La estrategia PreloadAllModules en acción.

El router también registró las declaraciones de ruta de los módulos para 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 hay decenas de módulos, su precarga agresiva realmente puede aumentar el uso de la red. Además, dado que el router debe registrar las rutas en todos los módulos precargados, puede generar cálculos intensivos en el subproceso de IU y provocar una experiencia del usuario lenta.

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

Para agregar un vínculo rápido a una app de Angular, puedes usar el paquete ngx-quicklink. Comienza instalando el paquete desde npm:

npm install --save ngx-quicklink

Una vez que esté disponible en tu proyecto, podrás usar QuicklinkStrategy especificando el preloadingStrategy del router e importando 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 a él. Cuando abras el panel de navegación lateral, verás que el router precarga la ruta "About":

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 tu aplicación contiene varios módulos de carga diferida, deberás importar el QuicklinkModule a un módulo compartido, exportarlo y, luego, importar el módulo compartido a los 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 los módulos de carga diferida.

Más allá de la precarga básica

Si bien la precarga selectiva a través de vínculo rápido puede acelerar significativamente la navegación, puedes hacer que tu estrategia de precarga sea aún más eficiente en la red con la precarga predictiva, que implementa Guess.js. Cuando se analiza un informe de Google Analytics o de otro proveedor de estadísticas, Guess.js puede predecir el recorrido de navegación de un usuario y precargar solo los fragmentos de JavaScript que probablemente se necesiten a continuación.

Puedes obtener información para 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 correcta 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.