CodeForge

Angular 21 de Cero a Experto / Signals a fondo

Por qué signals reemplazaron a zone.js

Teoría20 min20 XP

Esta lección no enseña una API nueva: explica el CAMBIO ARQUITECTÓNICO más profundo de Angular moderno. Durante una década, Angular supo cuándo repintar la pantalla gracias a una librería llamada zone.js que parcheaba el navegador entero. Signals hicieron eso innecesario. Entender por qué te da la intuición para escribir apps rápidas y para leer con sentido cualquier discusión sobre rendimiento en Angular.

El problema: ¿cuándo repinto?

Cualquier framework tiene que responder una pregunta: después de que pasa algo (un clic, una respuesta HTTP, un setTimeout), ¿qué parte de la pantalla actualizo? Angular necesitaba saber cuándo "algo pasó" para revisar si los datos cambiaron y repintar. La solución histórica fue zone.js.

Cómo funcionaba con zone.js

zone.js parcheaba (monkey-patch) todas las APIs asíncronas del navegador: addEventListener, setTimeout, fetch, Promise… Así, cada vez que ocurría cualquier evento asíncrono, zone.js avisaba a Angular: "pasó algo, revisa". Y Angular ejecutaba la DETECCIÓN DE CAMBIOS: recorría TODO el árbol de componentes de arriba abajo, comparando cada valor enlazado en cada template con su valor anterior, para ver qué repintar.

Cómo lo resuelven las señales

Una señal sabe QUIÉN la lee. Cuando cambia, no hace falta revisar todo el árbol: la señal avisa exactamente a los templates, computed y effect que dependen de ella, y solo eso se actualiza. El framework ya no pregunta "¿cambió algo en alguna parte?"; el dato mismo dice "cambié yo, y estos son los que me usan".

mental-model.ts
// Modelo VIEJO (zone.js): algo asíncrono ocurre →
//   Angular revisa TODO el árbol de componentes → repinta lo que cambió.
//   Costo: proporcional al tamaño de la app.

// Modelo NUEVO (signals): una señal cambia →
//   avisa SOLO a sus dependientes directos → se actualizan solo ellos.
//   Costo: proporcional a lo que realmente cambió.

Esto es "reactividad de grano fino": el trabajo de actualización es proporcional a lo que cambió, no al tamaño total de la aplicación. Una app con 10.000 elementos en pantalla, si cambias un contador, actualiza un elemento —no revisa los 10.000—.

Antes (zone.js) vs Ahora (zoneless con signals)

¿Cuál es la diferencia esencial entre la detección de cambios con zone.js y con señales?

Mini-reto

Sin código: 1) explica con tus palabras, como si se lo contaras a un colega, por qué un clic en un botón podía ser "caro" en el Angular de zone.js aunque solo cambiara un número; 2) describe qué gana una app al volverse zoneless; 3) razona por qué el requisito para zoneless es "usa señales para tu estado" —qué le falta a Angular para actualizar la vista si tu estado NO es una señal ni un evento que él conozca.

Qué sigue

Entiendes el porqué arquitectónico. Volvemos a la práctica: en el módulo anterior viste input() asomar como señal. La próxima lección profundiza en los INPUTS como señales —input(), input.required(), transformaciones— y en model() para el two-way binding entre componentes. Reactividad de grano fino aplicada a la comunicación entre piezas.