My understanding of angular change detection strategy from various articles and stackoverflow posts:
The change detection process includes:
- Updating inputs to children of a component.
- Run change detection for embedded views.
- Call
ngOnChanges
,ngDoCheck
,ngOnInit
on children if applicable. - Update content children in current component.
- Call
afterContentInit
,afterContentChecked
of children if applicable. - Update DOM interpolation of current component.
- Run change detection for child view.
- Call
afterViewInit
,afterViewChecked
of children if applicable.
Default change detection strategy: When a event (dom events, setTimeout, XHR etc) happens at any component, angular would run change detection for the entire application starting from top. All the steps above are repeated for all the components.
OnPush change detection strategy: Change detection is not triggered for a component unless
- When the component is first created a change detection is run.
- A reference to a input of the component changes.
- A event listener (ex:
(click)="onClick()"
) is triggered in the component or one of it's children - When a
async
pipe gets a new value from the observable
Some other interesting things:
All the steps in the change detection process listed above are run for
OnPush
change detection strategy too except DOM binding updates. Yes!ngDoCheck
,afterViewChecked
etc life cycle hooks are called even for components withOnPush
change detection strategy when a event happens in any part of application.When a
markForCheck
is called, it would mark the present component and all the parents in the hierarchy to be checked for changes. This forces change detection for these components.When a event happens in the application angular starts checking from root of application and then down the hierarchy. When a component is encountered it is checked if the component is marked for check.
If marked for check then change detection is run for the component. (DOM bindings are updated)
Else the component is checked if it has
OnPush
change detection strategy.If
OnPush
strategy, the input bindings are checked for any reference changes. If references have changed the change detection happens. (DOM bindings updated).Else change detection is run for the component (DOM bindings are re evaluated).
My Doubts:
- Is my understanding correct?
- What is the difference between a
embeddedView
andchildView
in a view. is this about direct children vs projected content of a component? - If in
OnPush
change detection strategy all steps except DOM Interpolation updates are done (i.e the complete application view hierarchy is traversed by angular and life cycle events called for every event) how does this still turn out to be more performant? Is DOM interpolation update a very costly task? - If i want to use a component inside another component with change detection strategy as
OnPush
i will have make sure to trigger changes that happen internally inside the component for example with axhr
request. Doesn't this create a coupling between the component and where it is used?