Optimización de Angular: Mejores Prácticas para 2024
Optimización de Angular: Mejores Prácticas para 2024
Durante mis más de 20 años desarrollando aplicaciones web, he visto cómo Angular ha evolucionado hasta convertirse en uno de los frameworks más potentes. Sin embargo, una aplicación Angular mal optimizada puede tener un rendimiento pobre. En este artículo, comparto las técnicas que uso para crear aplicaciones Angular ultra-rápidas.
Estrategia de Detección de Cambios OnPush
Una de las optimizaciones más impactantes es implementar la estrategia OnPush:
@Component({
selector: 'app-tarjeta-usuario',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="tarjeta-usuario">
<h3>{{ usuario.nombre }}</h3>
<p>{{ usuario.email }}</p>
</div>
`
})
export class TarjetaUsuarioComponent {
@Input() usuario!: Usuario;
}
Esta estrategia hace que Angular solo verifique el componente cuando:
- Las propiedades de entrada cambian
- Se disparan eventos
- Los observables emiten nuevos valores
Lazy Loading y División de Código
Implementa lazy loading para módulos de funcionalidades:
const rutas: Routes = [
{
path: 'usuarios',
loadChildren: () => import('./usuarios/usuarios.module').then(m => m.UsuariosModule)
},
{
path: 'productos',
loadComponent: () => import('./productos/productos.component').then(c => c.ProductosComponent)
}
];
Scroll Virtual para Listas Grandes
Para listas con muchos elementos, el scroll virtual es esencial:
<cdk-virtual-scroll-viewport itemSize="50" class="viewport">
<div *cdkVirtualFor="let item of items">{{ item.nombre }}</div>
</cdk-virtual-scroll-viewport>
Funciones TrackBy
Siempre usa funciones trackBy en bucles *ngFor:
@Component({
template: `
<div *ngFor="let usuario of usuarios; trackBy: trackByUsuarioId">
{{ usuario.nombre }}
</div>
`
})
export class ListaUsuariosComponent {
trackByUsuarioId(index: number, usuario: Usuario): number {
return usuario.id;
}
}
Análisis de Bundles
Analiza regularmente tus bundles:
ng build --configuration production --source-map
npx webpack-bundle-analyzer dist/tu-app/stats.json
Optimización de Imágenes
Usa el componente NgOptimizedImage de Angular:
<img ngSrc="/assets/hero-image.jpg"
width="1200"
height="600"
priority
alt="Imagen principal">
Estrategias de Precarga
Implementa precarga inteligente:
RouterModule.forRoot(rutas, {
preloadingStrategy: PreloadAllModules
})
Optimización de Observables
Usa operadores RxJS eficientemente:
// ❌ Evita esto
this.servicio.getDatos().subscribe(datos => {
this.procesarDatos(datos);
});
// ✅ Mejor así
this.datos$ = this.servicio.getDatos().pipe(
map(datos => this.procesarDatos(datos)),
shareReplay(1)
);
Signals para Estado Reactivo
Usa Angular Signals para un estado más eficiente:
@Component({
template: `
<p>Contador: {{ contador() }}</p>
<button (click)="incrementar()">+</button>
`
})
export class ContadorComponent {
contador = signal(0);
incrementar() {
this.contador.update(valor => valor + 1);
}
}
Web Workers para Tareas Pesadas
Mueve cálculos complejos a Web Workers:
// worker.ts
addEventListener('message', ({ data }) => {
const resultado = realizarCalculoComplejo(data);
postMessage(resultado);
});
// component.ts
const worker = new Worker('./worker.ts', { type: 'module' });
worker.postMessage(datos);
worker.onmessage = ({ data }) => {
this.resultado = data;
};
Mejores Prácticas que He Aprendido
- Mide primero, optimiza después - Usa Lighthouse y DevTools
- Implementa OnPush en componentes que no cambien frecuentemente
- Usa lazy loading para módulos grandes
- Optimiza imágenes y assets estáticos
- Implementa service workers para cache offline
- Monitoriza el rendimiento en producción
Herramientas de Monitoreo
// Métricas personalizadas
@Injectable()
export class MetricasService {
private observer = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log(`${entry.name}: ${entry.duration}ms`);
});
});
constructor() {
this.observer.observe({ entryTypes: ['measure'] });
}
}
Resultados Medibles
Aplicando estas técnicas he logrado:
- Reducción del 70% en el tiempo de carga inicial
- Puntuaciones Lighthouse superiores a 95
- Mejora del 60% en First Contentful Paint
- Reducción del 50% en el tamaño del bundle
Conclusión
La optimización de Angular requiere un enfoque sistemático y medición constante. Las técnicas que he compartido han sido probadas en aplicaciones empresariales con millones de usuarios.
Recuerda:
- La optimización prematura es la raíz de todos los males
- Mide el impacto de cada optimización
- Prioriza las optimizaciones por impacto vs esfuerzo
- Mantén un balance entre rendimiento y mantenibilidad
¿Qué técnicas de optimización has usado en tus proyectos Angular? ¡Comparte tu experiencia en los comentarios!
Compartir este post