
Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
Change Detection: Signals vs OnPush vs Default
Change Detection and Signals
One of the great things about signals is that it will reduce a great deal of the need for us to understand precisely how change detection works in Angular.
Maybe you are starting to notice a theme in this module — the older concepts that we are covering require a great deal of explanation to try and understand the mental model and how everything fits together. The newer alternatives are usually much easier to explain and are generally just more intuitive.
Before signals, there was a lot of benefit in understanding and, to an extent, “gaming” or “optimising” your application to better suit the change detection system and improve performance (or to understand why something changed but you aren’t seeing it render on screen).
I think it will still be important to understand how change detection works with signals, but it won’t be as important as it was before. There will also be much less of these strategies for improving change detection performance.
Unfortunately, although we already have signals available in Angular, the
change detection mechanisms that make full use of them are not yet stable. This
will likely be coming very soon. Our strategy throughout this course will
basically be to just use signals and approach change detection as if the new
change detection mechanisms have already been implemented. Then, when they
become available, there won’t be much if anything you will need to do to start
utilising the benefits of this approach. In the mean time, change detection will
work just fine with signals in our applications, the only downside is that —
until the change detection update is released — it will be slightly less
performant not using the OnPush
change detection strategy.
We will not be implementing the old style change detection techniques (like
using OnPush
), but as usual we will still cover the concepts as you will
likely run into Angular applications that are not using these newer approaches.
The rest of this lesson will be dedicated to understanding the old style of
change detection. I am using the term “old” loosely here, because most well
architected applications today use OnPush
. Unless you are exclusing working
with new Angular application code, it is still a concept you will need to
understand for a while.
As you will see, we are about to discuss a lot of ideas and nuances that need to
be kept in mind when utilising the old OnPush
change detection strategy for
optimising change detection. Whilst there is still plenty of depth in signals
change detection to uncover to deepen your knowledge of how Angular works under
the hood, the high level story of how change detection with signals works is
quite simple: if a signal is updated, the signal will handle notifying Angular
that a change has occurred, and Angular can update the specific thing that needs
updating.
As you’re about to see — this is a refreshingly simple idea. The “downside” is that we will need to use signals for any changes we want reflected in the template using this paradigm. With the old method, as complicated and ineffecient as it is, it did allow for basically any change to be reflected no matter how it was made.
Personally, I don’t see being forced to use signals as a downside as they are fantastically powerful and rather simple to use. I am going to be using signals anyway, so the change detection improvements basically come for free.
Change Detection: OnPush vs Default
To get right to the point: Angular needs to keep track of when things in your application change. Let’s say we have a class member in the class for my component:
@Component({ selector: 'app-home', template: ` <p>{{ name }}</p> <button (click)="changeName()">Change name</button> `,})export class HomeComponent { name = 'Josh';
changeName() { this.name = 'Kathy'; }}
The value for name
is initially Josh
and we are displaying that in the
template. But, we have a button that triggers the changeName
method when
clicked which will change this value to Kathy
. I encourage you to run this
example for yourself, because we are going to play with this a bit.
If you click the button, you might be unsurprised to see that the value displayed in the template changes. This is what we would want to happen, but the underlying mechanisms for Angular to achieve this seemingly simple task aren’t so simple.
We could cause a change to the template in a different way — what about
a setTimeout
that triggers the change after 2
seconds?
@Component({ selector: 'app-home', template: ` <p>{{ name }}</p> `,})export class HomeComponent implements OnInit { name = 'Josh';
ngOnInit() { setTimeout(() => (this.name = 'Kathy'), 2000); }}
Or, maybe we have a setInterval
changing the value every second:
@Component({ selector: 'app-home', template: ` <p>{{ value }}</p> `,})export class HomeComponent implements OnInit { value = 1;
ngOnInit() { setInterval(() => this.value++, 1000); }}
If you run these examples, you will see that in every case the value is updated correctly. Angular detects when these changes occur and updates the template.
How does Angular detect changes?
We aren’t going to get into the precise underlying mechanisms that allow Angular to detect and respond to changes. This can become useful for performance optimisation, but it isn’t something we need to get into right now.
Our main goal in this lesson will be to understand the difference between the
Default
change detection strategy, and the OnPush
change detection strategy.
To do that, we need to understand a little bit about how the default change
detection strategy works.
The key idea behind how Angular is able to achieve this is that it uses
something called Zone.js
to detect when any code runs that has the potential
to cause a change. The scenarios that might cause a change to your application’s
state include:
- Component initialisation
- Events being triggered (like our button click from before)
- Handling the response of an HTTP request
- MacroTasks such as
setTimeout()
andsetInterval()
Thanks for checking out the preview of this lesson!
You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).