CodeForge

Angular 21 de Cero a Experto / Routing

Lazy loading: cargar cada página solo cuando se visita

Teoría20 min20 XP

Cuando tu app crece, cargar todo el código de golpe al arranque la vuelve lenta —aunque el usuario solo abra la página de inicio—. El lazy loading resuelve esto: cada ruta carga su componente solo cuando alguien la visita. En React lo hacías con lazy() + Suspense; en Angular es aún más simple, integrado en la definición de rutas. Hoy haces que tu app arranque ligera y crezca sin penalización.

Llevar solo la maleta de hoy

loadComponent: cargar un componente perezosamente

En lugar de component: X (que incluye X en el bundle inicial), usa loadComponent con un import() dinámico:

app.routes.ts
export const routes: Routes = [
{ path: '', component: ListaGastosComponent },   // carga inmediata (la home)

{
  path: 'estadisticas',
  // se carga SOLO cuando el usuario visita /estadisticas
  loadComponent: () =>
    import('./estadisticas.component').then((m) => m.EstadisticasComponent),
},
{
  path: 'gasto/:id',
  loadComponent: () => import('./detalle-gasto.component').then((m) => m.DetalleGastoComponent),
},
];

El import('./...') dinámico le dice al bundler: "pon este componente en un archivo aparte". Cuando el usuario navega a /estadisticas, el navegador descarga ese archivo, y solo entonces. Tu bundle inicial adelgaza: la home no carga el código de las estadísticas ni del detalle.

loadChildren: cargar una sección entera

Para una sección con varias rutas (por ejemplo, todo un panel de administración), agrupas sus rutas en un archivo y las cargas juntas con loadChildren:

app.routes.ts
export const routes: Routes = [
{ path: '', component: ListaGastosComponent },
{
  path: 'admin',
  // carga admin.routes.ts (y sus componentes) solo al entrar a /admin/*
  loadChildren: () => import('./admin/admin.routes').then((m) => m.adminRoutes),
},
];
admin/admin.routes.ts
import { Routes } from '@angular/router';

export const adminRoutes: Routes = [
{ path: '',         loadComponent: () => import('./panel.component').then((m) => m.PanelComponent) },
{ path: 'usuarios', loadComponent: () => import('./usuarios.component').then((m) => m.UsuariosComponent) },
];
// todo /admin/* vive en su propio bundle, cargado al entrar a la sección

Toda la sección /admin se convierte en un "trozo" (chunk) separado. Un usuario normal que nunca entra a admin jamás descarga ese código.

Antes (loadChildren con NgModule) vs Ahora (loadComponent standalone)

Lazy en rutas vs @defer en la vista

Angular tiene dos formas de "cargar bajo demanda", para dos escalas distintas:

  • Lazy loading de rutas (loadComponent) — para PÁGINAS: no cargues el código de una ruta hasta que el usuario navegue a ella.
  • @defer (bloque diferido en el template) — para PARTES pesadas de una página que ya estás viendo: un gráfico costoso, un mapa, un editor enriquecido. Se cargan cuando entran en viewport o tras un tiempo, sin ser una ruta aparte. Lo verás a fondo en el módulo de nivel producción.

Ambos reducen el JavaScript inicial; eliges según si lo pesado es una página entera o un trozo de una página.

¿Qué logra usar `loadComponent: () => import('./x')` en lugar de `component: XComponent`?

Mini-reto

Convierte estas rutas a lazy: una app con '' (lista, carga inmediata), 'estadisticas', 'gasto/:id' y una sección 'admin' con dos subrutas. Escribe: 1) loadComponent para estadísticas y detalle; 2) loadChildren para admin, con su archivo admin.routes.ts. Explica qué código descargaría un usuario que solo abre la home.

Qué sigue

Tu app carga rápido y crece bien. Pero algunas páginas no deberían ser accesibles para cualquiera: el panel de admin necesita que estés logueado. La próxima lección son los guards —porteros que deciden si una navegación puede continuar—, en su forma moderna y elegante: funciones, no clases.