With the addition of Signals and the way they improve Change Detection, I'm wondering if I should start using Signals only (instead of class variables) in order to display data in my component template to improve performance?
Update data in your template using a variable:
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
@Component({
selector: 'app-foo',
standalone: true,
imports: [CommonModule],
template: `<div>Message from the component: {{ message }}</div>`,
})
export class TwoComponent {
public message = 'Hello World!';
// Random way to update the message and automatically trigger Change Detection
public changeMessage(value: string): void {
this.message = value;
}
}
VS update data in your template using a Signal:
import { CommonModule } from '@angular/common';
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-foo',
standalone: true,
imports: [CommonModule],
template: `<div>Message from the component: {{ message() }}</div>`,
})
export class FooComponent {
public message = signal('Hello World!');
// Random way to update the message signal and automatically trigger Change Detection
public changeMessage(value: string): void {
this.message.set(value);
}
}
In this example I have a very basic template and a string, of course the Change Detection impact could be bigger for complex objects, arrays or complex views. Also, in many situations the Signal might exist in your Service/Store layer.
UPDATE
It is to my understanding that if you use Signals only, Change Detection can be configured as OnPush
, which might also improve the performance.
In your examples, the code of the changeMessage()
method will not schedule a Change Detection cycle.
Currently, Angular uses ZoneJS to schedule Change Detection (CD) cycles. ZoneJS monkey-patches async DOM APIs and most of the DOM events.
To call changeMessage()
, you'll add some click
event handler or some setTimeout()
call - only because DOM events and async APIs are patched (and watched) by ZoneJS, Angular will know that it's time to run a CD cycle.
So it's not changeMessage()
triggering Change Detection, but the event you generate to call changeMessage()
.
The Angular team has plans to improve this situation, and components with the OnPush
strategy will not need ZoneJS (and it will significantly improve performance).
The best things you can do right now for performance:
OnPush
strategy in new components;OnPush
can be used either with Signals or with Observables + async
pipe.