Should I use Signals for any variable I want to display in my Angular 17+ component?

648 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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(). You can read more about Angular Change Detection here.

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:

  • Use the OnPush strategy in new components;
  • Use Signals for variables in templates of new components.

OnPush can be used either with Signals or with Observables + async pipe.