📌 Introducción: ¿Por qué es importante la optimización?
Cuando creamos aplicaciones en Angular, el rendimiento puede verse afectado si no manejamos correctamente el cambio de estado de los componentes. Esto se debe a que Angular revisa constantemente los cambios en la interfaz para actualizar el DOM de forma eficiente. Sin embargo, esta detección de cambios puede volverse costosa en términos de rendimiento si no la controlamos adecuadamente.
Aquí es donde entra en juego el Change Detection (Detección de Cambios) y, más específicamente, la estrategia OnPush.
🎯 Objetivo de este artículo: Entender cómo funciona el Change Detection en Angular y cómo podemos optimizar el rendimiento con OnPush.
🧐 ¿Qué es Change Detection en Angular?
Change Detection (Detección de Cambios) es el mecanismo que usa Angular para actualizar la interfaz de usuario cuando ocurre un cambio en el estado de la aplicación.
📌 Ejemplo básico
Cuando el usuario hace clic en un botón y cambia un valor, Angular detecta el cambio y actualiza el DOM:
{{ contador }}
(click)="incrementar()">Incrementar
export class MiComponente {
contador = 0;
incrementar() {
this.contador++;
}
}
En este caso, Angular detecta el cambio en contador
y actualiza la vista automáticamente.
🤔 ¿Pero cómo hace Angular para detectar los cambios?
🔍 Angular usa un proceso llamado Zone.js, que detecta eventos como:
✅ Eventos del usuario (clics, inputs, etc.)
✅ Llamadas a setTimeout
o setInterval
✅ Peticiones HTTP
Cada vez que detecta un cambio, Angular verifica todos los componentes del árbol para ver si algo ha cambiado.
⚠️ Problema: Si tenemos muchos componentes y Angular revisa todos en cada cambio, ¡puede volverse lento!
🚀 ¿Cómo optimizamos Change Detection con OnPush?
Por defecto, Angular usa la estrategia ChangeDetectionStrategy.Default, lo que significa que verifica todos los componentes en cada cambio, sin importar si realmente han cambiado.
💡 Aquí es donde entra en juego OnPush
🛠️ Implementando OnPush en un Componente
Si queremos mejorar el rendimiento, podemos decirle a Angular:
"Solo verifica este componente si cambia una de sus entradas (
@Input
)"
Esto lo logramos con ChangeDetectionStrategy.OnPush:
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
@Component({
selector: 'app-mi-componente',
template: `{{ dato }}`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MiComponente {
@Input() dato!: string;
}
📌 Ahora, este componente solo se actualizará cuando cambie su @Input
y no en cada cambio global.
🛠️ Ejemplo práctico de OnPush en acción
Imagina que tenemos una lista de productos en una tienda:
*ngFor="let p of productos" [producto]="p">
Y el componente ProductoComponent
:
@Component({
selector: 'app-producto',
template: `{{ producto.nombre }}`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductoComponent {
@Input() producto!: { nombre: string };
}
🔍 Diferencias clave:
Estrategia Default | Estrategia OnPush |
---|---|
Angular revisa todos los componentes en cada cambio | Solo revisa el componente si cambia su @Input
|
Puede causar ralentizaciones en grandes aplicaciones | Mejora el rendimiento significativamente |
🛠️ Cómo forzar detección de cambios con OnPush
Si usamos OnPush
, Angular no actualizará el componente automáticamente a menos que cambie su @Input
.
📌 ¿Pero qué pasa si queremos actualizarlo manualmente?
Podemos usar ChangeDetectorRef.markForCheck()
:
import { ChangeDetectorRef, Component } from '@angular/core';
@Component({
selector: 'app-mi-componente',
template: `{{ mensaje }}`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MiComponente {
mensaje = 'Hola Mundo';
constructor(private cd: ChangeDetectorRef) {}
cambiarMensaje() {
this.mensaje = 'Nuevo Mensaje';
this.cd.markForCheck(); // 🔥 Forzar actualización
}
}
✅ markForCheck()
indica a Angular que verifique este componente en la próxima detección de cambios.
Si queremos detener la detección de cambios por completo, podemos usar detach()
:
this.cd.detach(); // 🛑 Detiene la detección de cambios
Para volver a activarla:
this.cd.reattach();
🎯 ¿Cuándo usar OnPush?
📌 Úsalo cuando...
✅ Tienes listas grandes de elementos en ngFor
✅ Quieres mejorar el rendimiento de componentes que no cambian frecuentemente
✅ Estás trabajando con datos que solo se actualizan desde el servidor
📌 No lo uses cuando...
❌ Necesitas detectar cambios en variables locales sin @Input
❌ Dependencias internas del componente cambian constantemente
🏁 Conclusión: ¡Optimiza tu Angular como un Pro!
💡 El sistema de detección de cambios de Angular es poderoso, pero puede ser costoso si no lo manejamos bien.
🚀 OnPush es la clave para mejorar el rendimiento en componentes que dependen de datos externos.
🔥 Recapitulación rápida:
✅ ChangeDetectionStrategy.Default
revisa TODO en cada cambio 🔄
✅ ChangeDetectionStrategy.OnPush
revisa SOLO cuando cambia un @Input
🚀
✅ Podemos forzar actualizaciones con markForCheck()
🔥
✅ Podemos detener detecciones con detach()
🛑
Ahora que lo sabes, ¡aplícalo y haz que tus aplicaciones sean rápidas como un rayo! ⚡🚀
¿Qué te pareció esta explicación? 🤔
Si tienes alguna duda o quieres más ejemplos, dime y seguimos aprendiendo juntos. ¡Nos vemos en el próximo artículo, Master! 😎🚀