Lesson Description
The "onPush Change Detection" Lesson is part of the full, Advanced Angular: Performance & Enterprise State course featured in this preview video. Here's what you'd learn in this lesson:
Alex explains the onPush change detection strategy and how it limits checks to specific triggers like input changes and events. He shows how this approach improves performance by reducing unnecessary change detection runs and encouraging immutable state patterns.
Transcript from the "onPush Change Detection" Lesson
[00:00:00]
>> Alex Okrushko: In this module we're going to be doing performance improvements in our application. Typically in the application, when we talk about performance, there's two types of performances we want to improve. First one is the initial load. Right, we do want to get the application up and running in the browser as fast as possible. And second is runtime performance of the application, so when there's interaction, there's events, application is performing as fast as possible.
[00:00:38]
And then, so we're going to start with something that will improve mostly the runtime, but also a little bit on the initial load, and this is, we're going to go zoneless in this application. From Angular 2.0 up until recently, application change detection was driven by zone. What Zone does, it patches all the APIs, such as like set timeouts or HTTP requests completion or, you name it, all the APIs or even promise resolutions, it patches those APIs, so it's aware when those things happen, those things happen during asynchronicity.
[00:01:32]
We can also tell it directly to do certain things when we mark things as dirty in the components, it would also be aware that something has changed. And then Zone.js is just listening for those events, and then triggers the app tick, which basically starts change detection. I have slides here for this. These animations are courtesy of Christoph, he is one of the contributors and members of Angular Love.
[00:02:08]
I have the link for his article as well if you want to take a look so his animation is a courtesy of them so by default whenever we start change detection, it starts from the root and starts going breadth first, right, on through all the components, it just checks them just in case, is anything changed there or not, right? If something changed, it will re-render that component. Again, in most cases, it works pretty fast, works pretty good.
[00:02:46]
But we also have something that's called OnPush change detection. So if I go to the event details here, for example, we can specify change detection for every single component, and we can say that this component change detection strategy is OnPush. OnPush provides us with performance optimizations, it tells us that, hey, this component, don't check it just by itself, only check it if it was marked already dirty and we're going to talk about how it could be done or its inputs are changing.
[00:03:33]
And something I was referring before, very important is immutability in Angular. Inputs, if it's a string or a boolean, right, they're immutable, if you're passing the object, and you change one of the properties of the object, you have to make sure that you create a new reference for the entire object itself, right, if you're using OnPush. This allows Angular to only compare references of the inputs, and like, oh, I know, this component should be also checked because its input changed.
[00:04:05]
Also, it would check this component, or actually, yes, it will check this component, if there's an event that's incoming from this component, for example, if you have a button click in this component in the template. That would propagate up and mark all the components dirty all the way up to the root, through its chain, it will make them dirty and then change detection will check them all, so by default with Zone.js.
[00:04:42]
Angular will check all the components. It's pretty fast, it's pretty fast, and actually, it does it in the dev mode, if you're running in a dev mode, it does it twice, right? First it checks, and then in the dev mode, it rechecks it, so if you've seen expression changed after it's been checked before, when you have some little timeout or timer or something that's, this is where you'll analyze like, oh hold on, this snapshot is not the same as before, so something's up, right?
[00:05:10]
But in an actual application, it does it once, right, in the production application does it once, so you never see those errors, if you've seen them in a production application. Now, OnPush, if we mark some of the components OnPush, you can see that with the striped circles around them. What it would do, it will, if you have an event in this case in F, right, this is a click event.
[00:05:39]
Right, so it would mark that component dirty, and it will mark all the way again to the parents to dirty. However, then when the change detection starts running. It only will check the components or the branches that do not have OnPush. So I see here B, component B has an OnPush change detection strategy, so it's like, hey. I shouldn't be checked unless my inputs changed, or again, if there's an event coming out of it, so it won't check that B, and because it won't check that B, it won't check its children too, so C and D do not have OnPush, for example, but it cuts out the entire change detection, not going deep.
[00:06:25]
G will be checked anyway because G doesn't have OnPush and E doesn't have OnPush, so there are some changes with signals because signals changes will also tell, hey, check me and make myself dirty, and then all the way to the parents, right, so this is really powerful, you don't really need to have an event as well because Signal will already notify Angular as well that hey something here was changed, if we ideal state of our application, we have all components OnPush.
[00:07:07]
Right? And then it will automatically know which to change because the signal changed or we have a button click or we have input change right? So those would still propagate and this makes our change detection here look it just does three components in this case, it saves all the unnecessary work of checking that again just remind you. Dirty checking component is extremely fast operation, so if you never used OnPush, and your app's just working as it is, most likely you didn't really see that, but it does still extra work, right?
[00:07:41]
So the question is, why do we need to do extra work at runtime when we don't have to do any work at runtime.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops