2024 has been an interesting year for Angular. To me, four things stand out:
1. Long-term effects of the cooperation with Wiz
2. Incremental Hydration as a short-term result of this partnership.
3. The continued work on Signals, and
4. the introduction of zoneless.
Cooperation with Wiz
In March, at ng-conf, the Angular team announced their partnership with Wiz, Google’s internal framework that powers products like Google Search. Unlike Angular, Wiz is not developer-friendly but excels in performance, designed for applications that need to load instantly. Angular, in contrast, provides a better developer experience but has historically lagged in initial loading performance.
The goal is to integrate Wiz’s performance features into Angular, not the other way around. This collaboration represents a significant long-term commitment. It positions Angular to become a more integral part of Google’s internal projects and products.
I believe this action is not appreciated as much as it should be and stands out from all the technical features we’ve received in 2024. Even for companies that don’t need Wiz-level performance, this makes Angular a much safer and more future-proof choice.
Incremental Hydration
One of the first visible results of the Wiz partnership is in the area of hydration. At its core, hydration bridges the gap between server-side rendering and a fully interactive Angular application.
Earlier in the year, Angular introduced Event Replay, a foundational feature for server-side rendered (SSR) applications. It addresses the "uncanny valley" of SSR, where user interactions occur before Angular is fully initialized. Event Replay ensures these interactions are captured and replayed once Angular is ready.
In Angular 19, the game-changer arrived: Incremental Hydration. This allows developers to mark specific regions in the template and define criteria for hydration. These criteria can include user interactions, timeouts, or even avoiding hydration altogether for non-interactive regions.
Angular wasn’t a good fit for internet-facing applications with demanding initial-loading performance requirements. Now it has catapulted itself to the front, being avant-garde and—once word gets around—will become an attractive framework for a completely new market of developers and applications.
Signals
It is tempting to say that 2024 was not the year of Signals. Version 18 didn’t bring anything new, and the `effect` function is still in developer preview. Nevertheless, version 19 brought us `linkedSignal` and the `rxResource`/`resource` pair.
`linkedSignal` is a nice utility function that we can use instead of `effect` to create working copies of Signals with a dependency on the original.
`resource` is more than just a nice utility function. It bridges the gap between Signals and asynchronous tasks and is one of the missing pieces for a "holistic Signal experience". `resource` doesn’t just return a Signal. Its API includes the status, potential error information, a reload function, and an option to abort asynchronous tasks. It provides the foundation for any future feature that performs asynchronous operations.
With `resource`, we also see the path toward a Signal-based `HttpClient` alternative, which we now know will be called `httpResource`. The question of managing asynchronous tasks and their race conditions without RxJS has also been addressed. `resource` has a built-in `switchMap` implementation, and if we need more, we can always use `rxResource`, which comes with RxJS.
Zoneless
Having an experimental zoneless mode in Angular 18 was quite a surprise. When Signals arrived in the summer of 2023, their main selling point was being an enabler for zoneless execution. That also required so-called Signal Components, which would trigger Change Detection instead of relying on zone.js.
Over time, it became clear to the Angular team that zoneless and Signals are not necessarily coupled. By adjusting `markForCheck`, an essential function for every `OnPush` component, they found a solution. Instead of just marking the component as dirty, `markForCheck` now also triggers Change Detection. This simple change allows zoneless to be achieved with minimal effort.
The major change was using `markForCheck` as a trigger—probably much simpler than introducing Signal Components. But it gets even better. Existing applications and libraries don’t need to be rewritten. Zoneless works without Signals at all. In fact, applications using `OnPush` for all their components might already be zoneless without even realizing it.
Given the impact of such a tiny change to `markForCheck`, this was a brilliant move. It shows that giving an idea time to evolve can lead to faster results with far less effort than initially planned.