Angular ChangeDetectionStrategy和禁用zone.js

问题描述

我目前正在使用Ivy(v10.1.2)开发非常轻巧的Angular Elements。

当我不将zone.js导入polyfills.ts并在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中问了同样的问题,并得到以下答复(简短版本):

当我们禁用Zone.js时,我们仍然拥有变更检测器,但是没有人 将为我们运行更改检测。我们必须将组件标记为 弄脏自己。

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

它继续:

对于ChangeDetectionStrategy来说,它有点有用,因为所有 我在模板中使用的对象是不可变的。让我来 解释为什么这很重要。当变更检测运行时,它将检查 我在模板中使用的任何对象是否更改。如果我是 使用默认更改检测策略,它将检查任何对象 使用深度相等性检查,它将在组件树中消失 进入孩子并做同样的平等检查。就我而言,OnPush 会进行参照相等性检查,这就足够了,因为所有 我正在使用的对象是不可变的,除此之外,我仅 有一个组件而没有任何子组件。

总而言之,我禁用Zone.js来减小捆绑包的大小,因为我 每当我和我手动触发变更检测 启用了OnPush,因为我所有的对象都是不可变的, 通过减少改进实际变更检测的性能 支票数量。

因此,我的总结和总结

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