我希望深入了解更改检测器如何在我们的应用程序中运行的细节。最近,我发现我们重新渲染应用程序的次数远远超出了我们的需要,于是我提交了一份Angular issue。我已经能够修复所有我知道的渲染过多的地方,但现在我想要有一种简单的方法来确切地知道更改检测器何时运行,为什么它运行,以及运行时哪些组件是脏的。获取此信息的最佳和/或最简单方法是什么?
更新:因此您可以在AppView.detectChanges中设置一个断点,以便在更改检测器运行时中断,然后单步执行该代码,您可以看到正在检查的内容。然而,我仍然不确定如何轻松地确定是什么触发了更改检测器,或者是谁在标记要检查的组件。
发布于 2018-06-22 01:54:23
注意:这是开着的:“什么在触发变更检测器?”
我花了一些时间研究主题,但我得出的结论是,如果不修改angular源代码,就不容易做到这一点。然而,我可以分享一些我如何处理这个问题的技巧。
ApplicationRef.prototype.tick )上的更改检测。ApplicationRef.prototype.tick上创建断点。

onIvokeTask方法调用。

task变量。此变量存储有关触发更改检测的操作的信息。对于某些事件(setTimeout),callback属性将与我传递给setTimeout的回调完全相同,但对于单击事件,它也会回调,但由一些角度装饰器包装。但是,您可以通过其他属性(如eventName和target.)来确定操作

是的,我知道这太复杂了,但我不知道更好的解决方案。如果有人能做得更好,请分享它!:)
发布于 2017-09-29 16:10:42
另一种方法是创建自定义装饰器来添加ngDoCheck钩子并将其记录到页面中的组件,这样做的缺点是您必须将此装饰器添加到页面中的每个组件中:
(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 = {};您可以在控制台中查看calls,以获取调用次数最多的组件的一些统计信息。请记住,ngDoCheck调用并不意味着在组件上运行更改检测,而是指示更改检测在父组件上运行。
还不确定如何一致地确定实际触发更改检测的是什么。一些想法正在覆盖ngZone或ChangeDetector来记录实际的触发器。
发布于 2019-11-06 17:47:23
虽然调试本身仍然是一个难以实现的目标,但有一个带有accompanying article的practical demo至少可以更好地理解这一切是如何工作的。
编辑:另请参阅10 Things Every Angular Developer Should Know About Zone.js
https://stackoverflow.com/questions/40850766
复制相似问题