With each release of Angular there are enhancements in the Performance and developer experience. Let us see what all new features and enhancements made in Angular 19
Incremental Hydration
Incremental hydration is a performance optimization technique for Angular applications that enables selective hydration of content as needed, rather than hydrating the entire application upfront. This approach results in smaller initial bundles, improving load times and reducing layout shifts, thereby enhancing the user experience.
In traditional hydration, all content is hydrated at once, which can lead to longer load times and higher First Input Delay (FID). With incremental hydration, only specific sections of the app are hydrated when required, reducing the initial load and making the app feel more responsive. For example, content above the fold can now be hydrated without causing layout shifts, which was a challenge in previous versions of Angular.
Key Features:
1. Triggers for Hydration: Hydration can be triggered using several conditions like idle state, viewport visibility, user interaction, or after a specified duration. These triggers allow you to control when deferred content should be hydrated.
- Example: Use @defer (hydrate on idle) to load a large component when the browser is idle, avoiding delays during critical loading stages.
2. Customizable Hydration: Triggers like hydrate on interaction, hydrate on hover, and hydrate on timer give developers fine-grained control over when content is hydrated.
- Example: Use @defer (hydrate on interaction) to defer the hydration of a component until the user interacts with it.
3. Handling Nested @defer Blocks: Incremental hydration supports complex scenarios like nested @defer blocks, allowing for progressive hydration as needed.
4. Hydrate never: This option keeps content in a deferred state indefinitely, ideal for static or rarely changing sections of the application.
Example Code:
@defer (hydrate on idle) {
} @placeholder {
Large component placeholder
}
@defer (hydrate on viewport) {
} @placeholder {
Large component placeholder
}
Route-level render mode
In Angular v19, a new feature called Route-Level Render Mode allows developers to specify how each route should be rendered: server-side, client-side, or prerendered. This configuration gives developers fine-grained control over how different routes are handled during the server-side rendering (SSR) process, improving performance and flexibility.
- Server-Side Rendering (SSR): Routes that require server-side rendering are explicitly marked with RenderMode.Server.
- Client-Side Rendering: Routes that should be rendered only on the client side are marked with RenderMode.Client.
- Prerendering: Routes that do not require dynamic content can be prerendered at build time, improving load times and reducing server load.
The new ServerRoute interface allows you to specify the render mode for each route, and it works seamlessly with your existing route declarations. It also supports dynamic parameter resolution for prerendered routes.
Example Code:
export const serverRouteConfig: ServerRoute[] = [
{ path: '/login', mode: RenderMode.Server }, // Render login on the server
{ path: '/dashboard', mode: RenderMode.Client }, // Render dashboard on the client
{ path: '/**', mode: RenderMode.Prerender }, // Prerender all other routes
];
// Prerendering dynamic routes with parameters
export const routeConfig: ServerRoute = [{
path: '/product/:id',
mode: RenderMode.Prerender,
async getPrerenderPaths() {
const dataService = inject(ProductService);
const ids = await dataService.getIds(); // ["1", "2", "3"]
return ids.map(id => ({ id })); // Dynamic prerender paths based on product IDs
},
}];
Resource API
In Angular v19, the framework introduces the resource() API as an experimental feature to integrate asynchronous operations into Angular’s signals system. While signals have traditionally focused on synchronous data (like state management and computed values), the resource() API enables signals to handle asynchronous data dependencies, making it easier to manage and track the state of data that changes over time.
A resource in Angular consists of three parts:
- Request Function: Defines the dependency (e.g., a user ID) that will trigger the asynchronous operation.
- Loader: Executes the asynchronous operation (e.g., fetching data) when the request changes.
- Resource Instance: Exposes signals that track both the data (once fetched) and the current status (loading, resolved, errored).
The resource can be used in Angular components to handle dynamic, asynchronous data dependencies with built-in support for tracking loading and error states.
Example Code:
@Component(...)
export class UserProfile {
userId = input(); // Input for the user ID
userService = inject(UserService); // Injecting the user service
// Defining the resource with an async loader
user = resource({
request: this.userId, // Request depends on the user ID
// Fetching user data
loader: async ({ request: id }) => await userService.getUser(id),
});
}
Linked Signals
In Angular v19, a new primitive called linkedSignal is introduced to handle common UI patterns where mutable state needs to track changes in higher-level state. A typical use case is when you have a current selection in a UI that changes based on user input, but should reset when a list of available options changes. The linkedSignal provides a clean, declarative way to express this relationship without resorting to effects or manual state management.
A linkedSignal is a writable signal that depends on another signal and updates automatically when that signal’s value changes. It captures the dependency and allows for mutable state that resets based on changes in related data.
Example Code:
const options = signal(['apple', 'banana', 'fig']); // List of options
// Choice defaults to the first option but can be changed
const choice = linkedSignal(() => options()[0]);
console.log(choice()); // apple
// Changing the choice manually
choice.set('fig');
console.log(choice()); // fig
// When options change, choice resets to the new default value
options.set(['peach', 'kiwi']);
console.log(choice()); // peach
Standalone Defaults
In Angular v19, the standalone components feature, introduced in Angular v14, continues to evolve. As part of this update, Angular now defaults to standalone: true for components, directives, and pipes, making it the default behavior for new components. This change ensures that standalone components, which don’t require modules to function, become the primary way to structure Angular applications.
Additionally, Angular v19 provides a schematic that helps developers automatically update their codebase during an ng update. This schematic removes the standalone metadata property for all standalone components, directives, and pipes, and sets standalone to false for non-standalone components.
To further enforce this shift to modern APIs, Angular introduces the strictStandalone compiler flag. When enabled, this flag will throw an error if any component, directive, or pipe isn’t standalone, encouraging developers to adopt standalone components and follow best practices.
Zoneless Angular
In Angular v19, zoneless rendering is further developed and integrated to reduce Angular’s dependency on zone.js, a library historically critical for server-side rendering (SSR). Zone.js has been used to notify Angular when the rendering is complete, allowing the server to send the final page to the client. However, Angular v19 introduces a more efficient way to manage this process by eliminating the need for zone.js while still ensuring that server-side rendering waits until the app is fully ready.
To address scenarios where pending HTTP requests and navigation delays the rendering, Angular provides primitives in the Angular HttpClient and Router to delay the page send-off until the app is stable. Additionally, a new RxJS operator called pendingUntilEvent is introduced, allowing developers to notify the server when Angular is still rendering, thus preventing premature page delivery.
Example: Using pendingUntilEvent in SSR
Here’s how you can use the pendingUntilEvent operator to notify the server that Angular is still rendering and shouldn’t send the page to the client until it’s fully stable:
import { catchError } from 'rxjs/operators';
import { EMPTY } from 'rxjs';
subscription
.asObservable()
.pipe(
pendingUntilEvent(injector), // Waits until rendering is complete
catchError(() => EMPTY) // Handles errors silently
)
.subscribe();
- pendingUntilEvent: This operator listens for the rendering to complete, delaying the page delivery until Angular is done.
- catchError: Handles any errors during the subscription and ensures the process continues smoothly.
This mechanism ensures that server-side rendering waits for the app to fully initialize before sending the page to the user, improving performance and preventing issues caused by premature markup delivery.
Angular Material and CDK in v19
Angular v19 introduces significant enhancements to Angular Material and the Component Dev Kit (CDK), improving both theming and drag-and-drop functionality.
- Enhanced Theming API: Angular Material 3’s theming system is made easier to use. The new mat.theme mixin simplifies the creation of custom themes, reducing code duplication when applying themes to individual components.
- Component Overrides: A new Sass API (mat.sidenav-overrides) is introduced to allow component-specific style customizations, such as overriding individual design tokens (e.g., background colors).
- Two-Dimensional Drag and Drop: The Angular CDK now supports two-dimensional drag and drop, enabling mixed orientations for draggable items (vertical and horizontal).
- Tab Reordering: Angular CDK adds support for tab reordering, making it easy to implement draggable tabs, a feature already adopted by Google Cloud Console’s BigQuery.
- New Time Picker Component: A highly requested time picker component has been added to Angular Material, following accessibility standards and community feedback.
These updates enhance developer experience, customization, and usability in Angular apps, particularly around UI components.
Example: Simplified Theming with mat.theme
@use '@angular/material' as mat;
html {
@include mat.theme((
color: (
primary: mat.$violet-palette,
tertiary: mat.$orange-palette,
theme-type: light
),
typography: Roboto,
density: 0
));
}
mat.theme is used to define a custom theme with primary and tertiary colors, typography, and density in a single, simplified mixin, reducing the need for repetitive code.
Example: Two-Dimensional Drag-and-Drop with Mixed Orientation
@for (item of mixedTodo; track item) {
{{item}}
}
cdkDropListOrientation=”mixed” allows the drag-and-drop list to support both vertical and horizontal orientations, providing flexibility for UI design.
Instant Edit/Refresh with Hot Module Replacement (HMR)
Angular v19 introduces Hot Module Replacement (HMR) for styles by default, and experimental support for template HMR behind a flag. Previously, when you made changes to a component’s template or style, Angular CLI would rebuild the app and trigger a full page refresh, which could disrupt the developer flow. With HMR, changes to styles or templates are applied instantly, without refreshing the entire page or losing the application state, resulting in a faster and smoother development experience.
- Style HMR is enabled by default in Angular v19, allowing you to see style changes in real-time without a page refresh.
- Template HMR is experimental and can be enabled by setting a flag.
Example: Enabling Template HMR
To enable template HMR in Angular v19, use the following command:
NG_HMR_TEMPLATES=1 ng serve
This will enable live updates for both styles and templates, allowing you to modify and see changes immediately without refreshing the page.
Key Points:
- HMR for Styles: Enabled by default in Angular v19 for faster development.
- Template HMR: Experimental feature that can be enabled using the NG_HMR_TEMPLATES=1 flag.
- Instant Updates: Changes to styles and templates are reflected immediately without a page refresh, preserving the app’s state.
Conclusion
With exciting new features like Route-Level Render Mode and Incremental Hydration, Angular 19 makes apps faster and more effective. These improvements increase user experiences, decrease server strain, and speed up load times. Now that developers have more control over the rendering of routes and content, Angular is an even better framework for creating scalable and contemporary online apps. This is the ideal moment to discover Angular 19’s strong characteristics if you haven’t before!