Lazy Loading: Manejo de Rutas con Angular
Hace mucho tiempo que no escribo en el blog, la cuarentena, el trabajo y los estudios me tienen sin tiempo, pero hoy tengo un rato para escribir. El tema de hoy es Lazy Loading: Manejo de Rutas con Angular. Esto es un tema mucho muy importante en Angular, ahora vamos a ver porque, pero primero ¿Qué es Lazy Loading?
Lazy Loading
La traducción de este término es "Carga perezosa" y está relacionado a como Angular carga y arma los paquetes al momento de buildear el proyecto. Básicamente lo que va a hacer internamente el Lazy Loading es cargar solo lo que necesitemos en el momento adecuado. Voy a poner un ejemplo.
Supongamos que tenemos dos páginas o vistas. Una va a ser para visualizar la lista de usuarios (una grilla) y la otra va a ser para dar de alta un usuario (un formulario). Si nosotros no usamos Lazy Loading cuando estemos en la vista de lista de usuarios, Angular va a cargar (internamente, no se va a renderizar) la grilla y además el formulario lo que provoca que demore más tiempo en cargarnos la página (lo mismo va a pasar si vamos a alta de usuario, nos va a cargar las dos), entonces acá viene este patrón de diseño a ayudarnos y evitar que carguemos cosas innecesarias en el momento que no las necesitemos.
¿Aún esta confuso? Vamos a verlo con un dibujo que hice:
Esto sería sin tener el Lazy Loading, podemos observar que a pesar de entrar en una vista u otra cargamos TODO y esto no es optimo. Veamos ahora con Lazy Loading:
Si ven el segundo dibujo, solo cargamos lo que necesitamos según entramos a una u otra vista.
¿Cómo aplicamos Lazy Loading?
Voy a contarles teóricamente como lo hacemos y ahora vemos el código y los pasos que sigo yo cuando creo el proyecto y cada vez que creo una vista nueva o algo en el que quiero aplicar este patrón.
Para aplicar este patrón en cada vista o lugar que necesitemos este tiene que cumplir tres condiciones:
Tener un modulo.
Tener un routing.
Y llamarlo con loadchildren donde lo necesitemos.
Veamos código
Ahora si, pasemos al código. Primero me voy a crear un proyecto de cero con el famoso ng new "nombreDeProyecto" para mostrarles que pasos hago yo para aplicar esto.
Como vemos todavía no hay nada, así que vamos a crear una vista llamada Usuario que se va a llamar mediante Lazy Loading.
Cómo primer paso voy a crear el modulo y el routing de esta vista, con el comando ng g m "usuarios" --routing
Ahora creemos el componente usuarios con el comando ng g c "usuarios"

Nos queda el último paso que es agregarlo al routing de donde deseemos llamarlo y decirle que vamos a cargarlo con lazy loading.
Vamos a nuestro app.routing.ts y agregamos en nuestra const de routes lo siguiente:
const routes: Routes = [
{
path: 'usuarios',
loadChildren: () => import('./usuarios/usuarios.module').then(m => m.UsuariosModule) //Le decimos que importe el UsuariosModule (dentro de ahí esta también estan sus rutas)
}
];
Podemos ver que ya le estamos diciendo que cada vez que cargue la ruta /usuarios cargue unicamente lo que haya dentro de su modulo (UsuariosModule) de esa forma cada import que hagamos ahi dentro sólo se cargara ahí. Por ejemplo si llegamos a tener otra página llamada Clientes, hacemos lo mismo y si vamos a por ejemplo /clientes no vamos a cargar lo de /usuarios. De esta manera mejoramos la performance de nuestra app.
const routes: Routes = [
{
path: 'usuarios',
loadChildren: () => import('./usuarios/usuarios.module').then(m => m.UsuariosModule)
},
{
path: 'clientes',
loadChildren: () => import('./clientes/clientes.module').then(m => m.ClientesModule)
},
];
Obviamente para usar las rutas necesitamos agregar en nuestro app.component.html el router-outlet.
<router-outlet></router-outlet>
Usé este ejemplo de código en lugar del caso que expliqué mas arriba porque me pareció mas sencillo, pero vamos a hacer eso también ya que agrega un nivel de dificultad.
¿Cómo hago un lazy loading dentro de otro lazy loading?
¿Cómo se hace un router-outlet dentro de otro router-outlet?
Es MUY sencillo, solo va a cambiar un poco nuestro código.
Vamos al caso que explique mas arriba, yo quiero cargar solo el formulario ó la grilla cuando corresponda de usuarios (sabiendo que usuarios ya se está aplicando el lazy loading)
Vamos a hacer los mismos pasos de antes.
Creamos el modulo
Creamos el routing
Y lo llamamos donde lo necesitemos (con un leve cambio con respecto a lo otro)
ng g m "usuarios/listaUsuarios" --routing
ng g m "usuarios/usuario" --routing (este es el formulario)
(Sé que los mas expertos quizás me maten por esto que mostré arriba, pero es solo demostración, realmente lo que deberían hacer es tener solo un componente grilla que se muestre dentro de usuarios.component, pero bueno perdónenme, es solo para fines ilustrativos)
Ahora vamos a crear los componentes correspondientes
ng g c "usuarios/listaUsuarios"
ng g c "usuarios/usuario" (este es el formulario)
Sólo nos queda el último paso que es agregarlo dentro del routing (en este caso dentro de usuarios.routing.ts ya que va allí dentro) en el const de routes
const routes: Routes = [
{
path: '',
component: UsuarioComponent,
children:[
{
path: 'usuario',
loadChildren: () => import('./usuario/usuario.module').then(m => m.UsuarioModule)
},
{
path: 'listaUsuarios',
loadChildren: () => import('./listaUsuarios/listaUsuarios.module').then(m => m.ListaUsuariosModule)
}
]
}
];
Como ven, tenemos nuestro routes con el componente Usuario y con otro parámetro llamado children con nuestras rutas que deseamos cargar de manera lazy.
Lo que nos falta es agregar dentro de nuestro usuarios.component.html es el router.outlet
<router-outlet></router-outlet>
Y listo ! Ya aplicamos Lazy Loading y vimos como hacer un router outlet dentro de otro aplicando lazy loading
Pueden encontrar mas info en la página oficial de Angular
También les recomiendo ver la entrada que hice sobre guards que puede llegar a ir en conjunto con esto
Espero que les sirva !