A Different way of Detecting Changes
What & Why
Creating and Using Signals
Updating Signal Values
Getting Started with Signals
Angular's Signals feature allows developers to have full control over change detection, giving better performance and smaller bundle sizes. Unlike the automatic change detection mechanism, Signals require developers to manually tell Angular when the data changes, which may require slightly more work. However, the advantages of Signals are that they update only the parts of the UI where the data (or "signal") is used, leading to faster and more efficient performance. Additionally, with the use of the set()
, update()
, and mutate()
methods, developers have a more granular level of control over updating specific parts of the UI. Although version 16 of Angular doesn't allow for a full switch to Signals yet, it is hoped that future versions will allow for a complete transition and eliminate the need for the zone.js
library. Overall, Angular's Signals offer a promising approach to change detection that offers a level of control and performance optimization not found in the automatic change detection mechanism.
Signals vs Classic Change Detection
Classic Change Detection
Zone-based Change Detection
Under the hood, angular uses library called zone.js
Advantage/Disadvantages of Classic approach:
Changes are detected automatically
UI is updated automatically
Sounds perfect but there some downsides.
Performance could be improved
Bundle size is increased
Signals
No automatic change detection. You tell Angular when data changes
Angular updates the parts of the UI where the data ("signal") is used
Advantage/Disadvantages of Signals approach:
Slightly more work
But full control, better performance and smaller bundle
Signal Updating:
set()
update()
mutate()
Note: With version 16 we can't fully switch to signals yet but in future versions hopefully we will be able to fully switch to signals and we get rid of zone.js library.
Note: It is important to note that Angular's Signals feature is currently in Developer Preview mode, which means that the syntax and features are subject to change in future versions. There is lot more to come on this topic in future versions.
A detailed example of Counter App with both classic implementation and using signals implementation is at following Github Repo: BlogSignalsInNgVersion16
Here is how counterComponent implementation looks like with Signals:
import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NavComponent } from './nav.component';
@Component({
selector: 'app-signals',
standalone: true,
imports: [CommonModule, NavComponent],
template: `
<div class="main p-5">
<h3>Signals</h3>
<div>
<p>Counter: {{ counter() }}</p>
<div class="d-flex gap-3 justify-content-center">
<button class="btn btn-warning" (click)="decrement()">
Decrement
</button>
<button class="btn btn-success" (click)="increment()">
Increment
</button>
</div>
</div>
<h3 class="mt-5">Action Log</h3>
<ol>
<li *ngFor="let action of actions()">{{ action }}</li>
</ol>
</div>
`,
styles: [],
})
export class SignalsComponent {
public actions = signal<string[]>([]);
public counter = signal(0);
public increment(): void {
this.counter.set(this.counter() + 1);
this.actions.mutate((oldActions) => oldActions.push('INCREMENT'));
}
public decrement(): void {
this.counter.update((oldCounter) => oldCounter - 1);
this.actions.update((oldActions) => [...oldActions, 'DECREMENT']);
}
}
Signals: What's To Come?
As mentioned, the "Angular Signals" feature is not finished yet! Whilst the foundation (creating signals, reading signals, updating signals) is fully implemented - as a developer preview, though - some more advanced features are still missing.Signal-based components, for example.In the future, you'll be able to mark components as signal-based (presumably by adding the signals: true
flag to @Component
) to let Angular know that it should not use its regular change detection algorithm in such components.And that's just one feature, of course. In signal-based components, you'll also be able to get rid of many decorators like @Input()
or @Output()
(and others). You would use special functions instead:
@Input() title:string;
would become
title = input<string>();
But, again, this part is still missing! It's likely to be added with Angular 17. You can learn more about the complete planned (!) Signals API in the official RFCs: https://github.com/angular/angular/discussions/49685
Please note that this RFC is split up into four "sub-RFCs" that dive deeper into specific aspects of Angular. For example, this sub-RFC takes a closer look at the signal-based components mentioned above.