Angular ChangeDetectionStrategy 和禁用 zone.js

Angular ChangeDetectionStrategy and disabling zone.js

我目前正在研究非常轻量级的 Angular Elements with Ivy (v10.1.2)。

当我不在我的 polyfills.ts 中导入 zone.js 并在我的 main.ts 中“禁用”它时,如下所示:

platformBrowserDynamic()
  .bootstrapModule(AppModule, { ngZone: 'noop' })
  .catch(err => console.error(err));

那么我在组件上设置的哪种 ChangeDetectionStrategy 是否仍然相关?

所以,如果我通过将组件标记为脏 (ɵmarkDirty as markDirty) 并使用默认的 ChangeDetectionStrategy 手动触发它,Noop-ChangeDetector 会遍历整个树吗?如果我将其设置为 changeDetection: ChangeDetectionStrategy.OnPush,它会检查手边的组件吗?

我实际上在 great medium article 中问了同样的问题并得到了以下回复(简短版):

When we disable Zone.js, we still have the Change Detector, but nobody will run the change detection for us. We have to mark the Component as dirty ourselves.

这实际上回答了我的问题,因为我认为我们没有变更检测器,因为我们将成为变更检测器(因为我们自己将组件标记为脏)。

继续:

As for the ChangeDetectionStrategy it is slightly useful, because all of the objects that I am using in the template are immutable. Let me explain why this matters. When the Change Detection runs it will check if any object that I am using in the template changed or not. If I was using Default Change Detection Strategy, it would check any object with the deep equality check and it would go down the Component Tree into the children and do the same equality check. In my case, OnPush will do the referential equality check and that’s enough, because all of the objects that I am using are immutable and besides that I only have one component without any child components.

In summary, I disabled Zone.js to reduce bundle size, because I am manually triggering the Change Detection whenever it’s time and I enabled OnPush, because all of my objects are immutable and I am improving performance of the actual Change Detection by reducing number of checks.

所以我的总结

当禁用 zone.js(我们仍然有一个 ChangeDetector)并使用默认策略(而不是 OnPush)并手动触发更改检测(使用 markDirty)时,ChangeDetector 将检查整个树(假设每个组件都有默认的变更检测策略)。 但是当使用 OnPush 时,ChangeDetector 只会检查手边的组件。