Alonso Bermejo Pérez
Angular 19: Novedades
En los últimos años, Angular ha redoblado sus esfuerzos para mejorar tanto la experiencia del desarrollador como el rendimiento. Con cada versión, el framework introduce mejoras que, al combinarse, generan un impacto significativo. Angular 19 no es la excepción y llega con novedades diseñadas para facilitar el desarrollo de aplicaciones web rápidas, confiables y modernas.
Principales novedades en Angular 19
1. Vista previa de hidratación incremental
Una técnica avanzada para optimizar el rendimiento en casos de uso exigentes. Este enfoque permite manejar la hidratación de manera más eficiente, mejorando la velocidad y experiencia del usuario.
2. Control avanzado de rutas
Angular ahora permite un control más detallado sobre cómo y dónde se renderizan las rutas:
- Opciones de renderizado: Elige entre cliente, servidor o durante la fase de construcción.
- Resolución de parámetros: Posibilidad de resolver parámetros de ruta durante el prerenderizado.
3. Esquemas actualizados para mejores prácticas
El framework introduce soporte para alinearse con las últimas mejores prácticas de desarrollo, incluyendo:
- Inputs y outputs más robustos.
- Consultas (queries) optimizadas para mejorar el rendimiento.
- Inyección de dependencias basada en
inject
. - Un nuevo sistema de construcción más eficiente.
4. Nuevas primitivas de reactividad
La reactividad en Angular sigue evolucionando con:
- Estabilización de primitivas reactivas clave.
- Introducción de nuevas funcionalidades:
linkedSignal
: Simplifica la gestión de estados vinculados.resource
: Optimiza la administración de recursos y estados.
5. Mejoras en calidad de vida (QoL)
El equipo de Angular ha escuchado a la comunidad, incorporando funcionalidades solicitadas que mejoran la experiencia del desarrollador:
- Un componente de selección de hora.
- Eliminación automática de importaciones no utilizadas.
- Ejecución de esquemas mediante el servicio de lenguaje.
- Soporte para Hot Module Replacement (HMR) en estilos.
- ¡Y mucho más!
Angular continúa posicionándose como uno de los frameworks líderes en el desarrollo web moderno gracias a su enfoque en el rendimiento. En Angular 19, se introducen innovaciones que mejoran significativamente la experiencia del usuario y optimizan la carga de aplicaciones, adaptándose a casos de uso más exigentes. Entre estas mejoras destacan el soporte para un Angular sin zonas (zoneless), la integración del renderizado del lado del servidor (SSR) en la CLI y colaboraciones clave con Chrome Aurora en tecnologías como hidratación e imágenes optimizadas.
Hidratación incremental: una nueva frontera en rendimiento
La hidratación incremental, presentada como vista previa para desarrolladores en Angular 19, es una solución avanzada inspirada en las deferrable views de la versión 17. Este enfoque permite optimizar el JavaScript cargado para cada página al “activar” partes de la interfaz de usuario solo cuando sea necesario.
¿Qué es la hidratación incremental?
Se trata de un mecanismo que permite cargar e hidratar dinámicamente partes específicas de la interfaz de usuario bajo demanda, utilizando la anotación de plantillas con la sintaxis conocida de @defer. Por ejemplo:
@defer (hydrate on viewport) {
<shopping-cart/>
}
En este caso, el componente <shopping-cart>
no será descargado ni activado hasta que entre en el área visible del usuario (viewport), lo que reduce considerablemente el impacto en el rendimiento.
Demostración práctica: un flujo típico
Un caso común de uso de esta funcionalidad es una página de comercio electrónico renderizada del lado del servidor. El flujo sería el siguiente:
- Estado inicial: La página se muestra en escala de grises, indicando que los scripts de la interfaz aún no están activos.
- Interacción: Cuando el usuario interactúa con un componente (por ejemplo, el carrito de compras o un filtro), Angular descarga e hidrata ese componente.
- Estado final: El componente se activa, pierde el estilo en escala de grises y muestra un borde púrpura para señalar que está completamente funcional.
Este enfoque aprovecha la repetición de eventos (event replay), una funcionalidad introducida en Angular 18 y utilizada en servicios como Google Search, que asegura que los eventos del usuario se guarden y se ejecuten una vez que los componentes correspondientes estén activos.
Cómo probar la hidratación incremental
Si ya utilizas SSR e hidratación completa, puedes habilitar esta funcionalidad fácilmente:
- Configura el bootstrap del cliente:
import {
provideClientHydration,
withIncrementalHydration,
} from "@angular/platform-browser";
provideClientHydration(withIncrementalHydration());
- Anota tus plantillas con
@defer
:
@defer (hydrate on viewport) {
<component-name/>
}
Con esta configuración, Angular cargará e hidratará únicamente los componentes necesarios, activándolos según los disparadores definidos (como cuando el componente entra en el viewport).
La hidratación incremental en Angular 19 no solo mejora el rendimiento inicial de las aplicaciones, sino que también permite manejar interacciones complejas de manera eficiente. Con esta herramienta, los desarrolladores pueden crear aplicaciones modernas, rápidas y adaptadas a las demandas de los usuarios actuales.
Reproducción de eventos activada por defecto en Angular 19
En las aplicaciones renderizadas del lado del servidor (SSR), un desafío frecuente es el “vacío” que ocurre entre la interacción del usuario y la descarga del código necesario para procesar esas acciones. Angular 19 resuelve este problema de manera elegante con la funcionalidad de reproducción de eventos (event replay).
¿Qué es la reproducción de eventos?
La reproducción de eventos captura las interacciones del usuario mientras la aplicación está cargando y las reproduce automáticamente cuando el código necesario para manejarlas está disponible. Esto asegura que ninguna acción realizada por el usuario se pierda, incluso si la interfaz aún no está completamente activa.
Ejemplo práctico
Imagina una tienda en línea donde el usuario puede interactuar con un botón de “Añadir al carrito” antes de que se cargue todo el JavaScript necesario para la interacción:
- Estado inicial: La página se muestra en escala de grises, indicando que el JavaScript aún no se ha descargado.
- Interacción: El usuario hace clic varias veces en el botón “Añadir al carrito”.
- Reproducción: Angular registra esos clics y, una vez que la aplicación está lista, reproduce los eventos para reflejar la cantidad correcta de productos en el carrito.
Este enfoque garantiza que las interacciones del usuario no se pierdan, ofreciendo una experiencia fluida y confiable.
Cómo habilitar la reproducción de eventos
Si utilizas SSR, esta funcionalidad ya viene habilitada por defecto en nuevas aplicaciones. Sin embargo, también puedes configurarla manualmente en tu proyecto existente con el siguiente código:
import {
provideClientHydration,
withEventReplay,
} from "@angular/platform-browser";
bootstrapApplication(App, {
providers: [provideClientHydration(withEventReplay())],
});
Este fragmento asegura que Angular capture y reproduzca automáticamente cualquier evento de usuario mientras la interfaz de usuario se inicializa.
Una solución robusta y probada
La reproducción de eventos se basa en la librería Event Dispatch, una tecnología que ha sido probada por más de una década y utilizada en servicios de alto tráfico como Google Search. Introducida como vista previa en Angular 18, ahora se ha consolidado como una característica estable en Angular 19.
Con esta funcionalidad, Angular refuerza su compromiso con el rendimiento y la experiencia del usuario, eliminando los vacíos de interacción en aplicaciones SSR y permitiendo que los desarrolladores construyan aplicaciones rápidas y fiables desde el primer momento. 🚀
Modos de renderizado por ruta en Angular 19: Flexibilidad y optimización
Angular 19 introduce una nueva funcionalidad que transforma la forma en que las aplicaciones manejan el renderizado de rutas. Ahora puedes decidir si una ruta se renderiza en el servidor, en el cliente o mediante prerenderizado, según los requisitos específicos de tu aplicación. Esta flexibilidad permite optimizar el rendimiento y adaptarte a casos de uso concretos con facilidad.
¿Cómo funcionan los modos de renderizado por ruta?
Cuando habilitas el renderizado del lado del servidor (SSR), Angular aplica ciertos comportamientos predeterminados:
- SSR para rutas con parámetros dinámicos.
- Prerenderizado para rutas estáticas.
Con Angular 19, puedes personalizar estos comportamientos utilizando la nueva interfaz ServerRoute
. Por ejemplo:
export const serverRouteConfig: ServerRoute[] = [
{ path: "/login", mode: RenderMode.Server }, // Renderizado en el servidor
{ path: "/dashboard", mode: RenderMode.Client }, // Renderizado en el cliente
{ path: "/**", mode: RenderMode.Prerender }, // Prerenderizado
];
Este enfoque híbrido te permite asignar modos de renderizado específicos para cada ruta, optimizando recursos y mejorando la experiencia del usuario.
Resolución de parámetros en rutas dinámicas
Angular 19 también simplifica el manejo de parámetros durante el prerenderizado de rutas dinámicas. Con la función getPrerenderPaths
, ahora puedes resolver automáticamente los valores de los parámetros y reutilizar la lógica de tu aplicación para generar rutas prerenderizadas con datos concretos.
Ejemplo práctico:
export const routeConfig: ServerRoute = [
{
path: "/product/:id",
mode: "prerender",
async getPrerenderPaths() {
const dataService = inject(ProductService); // Inyectar un servicio
const ids = await dataService.getIds(); // Obtener IDs dinámicos
return ids.map((id) => ({ id })); // Sustituir ":id" por valores reales
},
},
];
En este caso:
- La ruta
/product/:id
se prerenderiza con datos concretos. - La función
getPrerenderPaths
obtiene dinámicamente los valores deid
desde un servicio. - Los parámetros dinámicos son reemplazados antes de servir la página.
Beneficios de los modos de renderizado por ruta
- Optimización del rendimiento: Renderiza únicamente donde y como sea necesario.
- Flexibilidad: Configura el modo de renderizado para cada ruta de forma precisa, permitiendo una estrategia híbrida.
- Reutilización de lógica: Con la función
inject
, puedes aprovechar servicios existentes en tu aplicación durante el prerenderizado.
Prueba y adopta esta funcionalidad
Los modos de renderizado por ruta están disponibles como una vista previa para desarrolladores, lo que significa que puedes comenzar a experimentar con ellos hoy mismo para mejorar el rendimiento y la arquitectura de tu aplicación.
Renderizado del lado del servidor con Angular sin Zone.js
Angular 19 continúa avanzando hacia un entorno zoneless, eliminando la dependencia de zone.js
en el renderizado del lado del servidor (SSR). Este enfoque comenzó de manera experimental en Angular 18 y ahora está más refinado, ofreciendo un rendimiento mejorado y mayor control para los desarrolladores.
¿Qué significa Angular sin Zone.js?
Tradicionalmente, zone.js
ha sido una parte esencial de Angular para:
- Detectar automáticamente cuándo una aplicación ha terminado de renderizarse.
- Notificar al servidor que el HTML está listo para enviarse al cliente.
Con Angular zoneless, esta dependencia se elimina, adoptando un enfoque más explícito y moderno. Angular identifica dos casos clave para determinar cuándo el SSR debe finalizar:
- Solicitudes pendientes, como llamadas HTTP.
- Navegaciones internas, relacionadas con el sistema de enrutamiento.
Para gestionar estas situaciones, Angular utiliza primitivas específicas de los paquetes HttpClient
y Router
, asegurando que el servidor espere hasta que la aplicación esté completamente lista para ser entregada al cliente.
Nueva primitiva RxJS: pendingUntilEvent
Angular introduce un operador de RxJS llamado pendingUntilEvent
, diseñado para notificar al servidor cuando el renderizado ha concluido. Esta herramienta es especialmente útil en aplicaciones con procesos asíncronos complejos.
Ejemplo de uso:
subscription
.asObservable()
.pipe(
pendingUntilEvent(injector), // Esperar hasta que ocurra un evento específico
catchError(() => EMPTY), // Manejo de errores
)
.subscribe();
Cómo funciona:
- La aplicación se considera lista cuando el operador emite un valor.
- El servidor recibe la notificación y procede a enviar el HTML completamente renderizado al cliente.
Cómo probar Angular Zoneless en v19
Si estás utilizando SSR, puedes habilitar esta funcionalidad configurando los paquetes HttpClient
y Router
. Al implementar la nueva primitiva pendingUntilEvent
, obtendrás:
- Mayor control: Define explícitamente cuándo la aplicación está lista para servirse.
- Optimización del flujo: Asegura que todos los datos estén preparados antes de enviar la página.
Beneficios del enfoque Zoneless
Reducción de dependencias: Elimina zone.js, simplificando la base de código y reduciendo el peso de la aplicación. Rendimiento mejorado: Focaliza los procesos en lo esencial, acelerando el renderizado. Control explícito: Permite a los desarrolladores gestionar directamente cuándo el SSR está completo.
Mejoras en la experiencia del desarrollador con Angular v19
La versión 19 de Angular se centra en potenciar tanto el rendimiento como la experiencia del desarrollador. Estas mejoras buscan optimizar el ciclo de desarrollo, ofrecer herramientas más flexibles y promover prácticas modernas. A continuación, exploramos las principales novedades:
1. Reemplazo en caliente de módulos (HMR) para estilos y plantillas
El reemplazo en caliente de módulos (HMR) ahora permite que los desarrolladores actualicen estilos y plantillas sin necesidad de recargar la página completa, lo que preserva el estado actual de la aplicación.
Antes de Angular v19: Modificar un estilo o plantilla implicaba una reconstrucción completa de la aplicación, seguido de un refresh del navegador, perdiendo el estado de la app.
Con Angular v19:
- Estilos: Los cambios se reflejan inmediatamente sin recargar la página.
- Plantillas (experimental): Soporte para reemplazo en caliente al modificar plantillas.
Cómo habilitar HMR para plantillas:
NG_HMR_TEMPLATES=1 ng serve
Para desactivar esta función:
ng serve --no-hmr
Beneficios:
- Ciclos de desarrollo más rápidos.
- Flujo de trabajo ininterrumpido.
- Configuración automática para estilos (habilitado por defecto).
2. Componentes Standalone por defecto
Desde Angular 14, los componentes standalone han sido una de las características más populares. En Angular v19, esta funcionalidad ahora es predeterminada.
¿Qué significa?
- Los componentes standalone no dependen de módulos.
- Se configuran automáticamente como standalone, simplificando la creación de componentes, directivas y pipes.
Actualización automática: Angular v19 incluye un schematic que:
- Elimina la propiedad standalone en componentes standalone existentes.
- Configura automáticamente standalone: false en componentes que no son standalone.
Ventajas:
- Transición fluida a un enfoque moderno y modular.
- Mayor coherencia en la estructura del proyecto.
Aplicación estricta de Standalone:
Para garantizar el uso de componentes standalone en tu proyecto, habilita la opción strictStandalone
:
{
"angularCompilerOptions": {
"strictStandalone": true
}
}
3. Mejoras en herramientas de pruebas
El enfoque de Angular hacia las pruebas sigue evolucionando:
Novedades en Angular v19:
-
Soporte para Karma en combinación con el nuevo application builder.
-
Mejora de tiempos de construcción en pruebas unitarias.
-
Herramientas optimizadas para cargar archivos y mantener compatibilidad. Futuro de Karma:
-
Angular planea descontinuar Karma a mediados de 2025.
-
Se evaluarán runners alternativos (como Jest o Web Test Runner) basándose en las necesidades de la comunidad.
Beneficios:
- Pruebas más rápidas y confiables.
- Compatibilidad con herramientas avanzadas del builder.
4. Seguridad mejorada con CSP basada en hashes
Angular introduce soporte en vista previa para la Política de Seguridad de Contenidos (CSP) basada en hashes, en colaboración con el equipo de seguridad de Google.
¿Qué es CSP basada en hashes?
- El navegador genera un hash único para cada script inline en el index.html.
- Solo scripts con un hash autorizado pueden ejecutarse.
Ventajas:
- Protección contra XSS: Evita que scripts maliciosos se ejecuten en la aplicación.
- Mayor seguridad: Solo scripts previamente autorizados son permitidos. Cómo habilitarlo:
En el archivo angular.json, activa la propiedad autoCSP:
{
"projects": {
"my-app": {
"architect": {
"build": {
"options": {
"autoCSP": true
}
}
}
}
}
}
Evolución de la Reactividad en Angular v19
Estabilización de Inputs, Outputs y View Queries
Angular v19 marca un avance en la reactividad con la estabilización de las APIs de inputs, outputs y view queries, herramientas clave para gestionar datos en componentes. Estas APIs ahora están listas para su uso en producción, y Angular facilita la migración mediante schematics que automatizan el proceso:
- Migración de Inputs:
ng generate @angular/core:signal-input-migration
- Migración de Outputs:
ng generate @angular/core:output-migration
- Migración de Queries:
ng generate @angular/core:signal-queries-migration
Además, puedes realizar todas las migraciones juntas con:
ng generate @angular/core:signals
⚠️ Nota: Los inputs basados en señales son de solo lectura, por lo que podrían requerir ajustes manuales si tu aplicación los modifica directamente.
linkedSignal: Mejorando Dependencias entre Estados
linkedSignal
, una nueva API experimental, facilita la gestión de dependencias entre estados relacionados, como una selección actual vinculada a una lista de opciones.
Ejemplo básico:
const options = signal(["manzana", "banana", "higo"]);
const choice = linkedSignal(() => options()[0]);
console.log(choice()); // 'manzana'
choice.set("higo");
console.log(choice()); // 'higo'
options.set(["pera", "kiwi"]);
console.log(choice()); // 'pera'
🛠 Casos avanzados: También permite manejar estados anteriores para preservar elecciones específicas. Esta herramienta simplifica la lógica en interfaces dinámicas.
resource(): Integrando Operaciones Asíncronas
La nueva API experimental resource() permite combinar señales con datos asincrónicos, integrando operaciones como solicitudes HTTP directamente en el grafo de reactividad.
Ejemplo:
@Component({...})
export class UserProfile {
userId = input<number>();
userService = inject(UserService);
user = resource({
request: this.userId,
loader: async ({ request: id }) => this.userService.getUser(id),
});
}
Ventajas:
- Gestión automática de estados (cargando, error, etc.).
- Integración con RxJS a través de rxResource para compatibilidad con observables.
🎯 Objetivo: Hacer que la gestión de datos asincrónicos sea tan fluida como la de datos sincrónicos.
Estado de la API de Efectos
La API de efectos continúa en developer preview mientras se recopila retroalimentación. Aunque Angular ha ajustado su temporización para mejorar la alineación con casos de uso, su evolución sigue abierta a cambios para satisfacer necesidades emergentes.
Modo Zoneless: Hacia un Angular sin Zone.js
Angular avanza hacia un modelo zoneless más eficiente. Este enfoque elimina la dependencia de zone.js, mejorando el rendimiento y simplificando la gestión del cambio de detección.
Configuración para un nuevo proyecto:
ng new [nombre-proyecto] --experimental-zoneless
Habilitación en un proyecto existente:
bootstrapApplication(App, {
providers: [provideExperimentalZonelessChangeDetection()],
});
🛠 Próximos pasos:
- Prueba experimental en aplicaciones reales.
- Mejora continua basada en retroalimentación, con estabilización esperada para 2025.
Angular v19
consolida su compromiso con la reactividad, la eficiencia y la experiencia del desarrollador. Desde la estabilización de inputs, outputs y view queries hasta la introducción de herramientas como linkedSignal y resource(), este lanzamiento representa un paso importante hacia un Angular más ágil, moderno y poderoso. Además, el enfoque zoneless y la integración de actualizaciones automáticas en los editores refuerzan la visión de Angular como un framework diseñado para facilitar el desarrollo de aplicaciones de alto rendimiento.
Estas mejoras no solo simplifican la gestión de estados y operaciones asincrónicas, sino que también abren nuevas posibilidades para crear aplicaciones más reactivas y sostenibles. Angular sigue evolucionando con cada versión, y esta actualización es una invitación a explorar y adoptar estas herramientas en tus proyectos.
¿Te ha gustado este contenido?
Si encuentras útil esta información, dale like a este post y sígueme para no perderte las últimas novedades sobre Angular y desarrollo web. ¡Juntos podemos mantenernos siempre al día con las mejores prácticas y tendencias en tecnología! 🚀