I'm looking to get into the gritty details of how the change detector runs in our application. Recently I discovered that we were re rendering our application far more than we needed to and filed an Angular issue. I've been able to fix all the places that I know are rendering more than they should but now I want to have an easy way to know exactly when the change detector is running, why it is running, and what components are dirty when it runs. What is the best and or easiest way for me to obtain this information?
UPDATE: So you can set a break point in AppView.detectChanges
in order to break whenever the change detector runs and then stepping through that code you can see what is being checked. However, I'm still not sure how to easily determine what is triggering the change detector or who is marking the components for check.
NOTE: this is on: "What is triggering the change detector?"
I spent some time investigating topic, but I came to conclusion it can't be done easily without modifying angular source code. However, I can share some tips how I approach this problem.
ApplicationRef.prototype.tick
).ApplicationRef.prototype.tick
in core.js file.onIvokeTask
method call.task
variable in current scope. This variable stores information about action which triggered change detection. For some events (setTimeout
), callback
property will be exactly the same callback which I passed into the setTimeout
, but for e.g. click event, it would also callback, but wrapped by some angular decorators. However, You can somehow determine action by another properties like eventName
and target
.Yeah, I know it's too complicated, but I don't know better solution. If anybody can do it better, please share it! :)
Another approach is to create custom decorator to add ngDoCheck
hook and log it for components in your page, the drawback of this that you'll have to add this decorator to every component in your page:
(window as any).calls = {};
export function debug() {
return (constructor: any) => {
if (!constructor.prototype.ngDoCheck) {
constructor.prototype.ngDoCheck = () => {
console.log("ngDoCheck", constructor.name);
const calls = (window as any).calls;
calls[constructor.name] = calls[constructor.name] ? calls[constructor.name] + 1 : 1;
};
}
};
}
(window as any).resetCalls = () => (window as any).calls = {};
You can check calls
in your console for some statistics of what components are getting called most.
Have in mind that ngDoCheck
call doesn't mean change detection runs on that component, it's indication that change detection is running on parents component.
Not yet sure how to determine consistently what's actually triggering change detection. Some ideas are overriding ngZone
or ChangeDetector
to log actual triggers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With