【问题标题】:Angular2 OnPush change detection and ngForAngular2 OnPush 变化检测和 ngFor
【发布时间】:2017-06-23 08:51:12
【问题描述】:

我有一个父组件,它使用ngFor 显示子组件列表。我注意到随着孩子数量的增加,性能变得非常糟糕,因此我将两者都更改为 OnPush 更改检测策略。

这有很大帮助,但仍然有少数情况会减慢速度,我可以看到这是由于不必要地对每个孩子执行了更改检测。

一个例子是当子组件内部有一个点击事件时——即使没有改变输入并且它只是触发一个动画,由于某种原因,正在为父组件执行更改检测,结果是为每个子组件执行以及(即使ngFor 背后的模型根本没有改变并且它是OnPush 策略......)。我原以为这种“孤立”事件应该只触发该特定子组件中的更改检测,而不是向上传播(我实际上尝试了event.stopPropagation()event.preventDefault(),但没有成功)。

所以我想知道两件事:

1) 有什么方法可以更好地控制实际运行的事件更改检测以及它是否也触发父组件更改检测?

2) 在每个子组件(来自 ng2translate)中大量使用“翻译”管道会大大减慢应用程序/更改检测速度吗?

下面的示例 plunkr 以显示问题所在。基本上,如果我单击 ngFor 列表中的任何项目,它就会对每个孩子进行更改检测,而不仅仅是受影响的孩子,我想知道是否有任何方法可以抑制这种情况。

https://plnkr.co/edit/mD8HCbwq0cEwPt7itpCf

【问题讨论】:

    标签: performance angular angular2-changedetection


    【解决方案1】:

    1) 你可以使用ChangeDetectorRef.detach()

    https://angular.io/docs/js/latest/api/core/index/ChangeDetectorRef-class.html#!#detach-anchor

    从变化检测器树中分离变化检测器。

    在重新连接之前不会检查分离的变化检测器。

    这也可以与 ChangeDetectorRef 结合使用来实现本地更改检测检查。

    2) 管道(如果它们是纯的,这是默认的)仅在管道值或参数发生变化时才被调用,因此没有性能劣势。

    【讨论】:

    • 谢谢。我已经用 plunkr 更新了我的问题,以更好地证明问题。但基本上没有办法“抑制”同级更改检测,我需要完全分离更改检测并自行处理?
    • @Zyga 我认为您的子组件中没有更改检测。将 console.log 放在 isVisible 方法中。它只会为您单击的项目调用。 plnkr.co/edit/v514QJfNYXe13KKh23L2?p=preview ngDoCheck 正在为所有儿童运行。如果你删除OnPush,那么你所有的孩子都会被检查
    • @Zyga Angular 在第一次更改检测循环后将OnPush 组件标记为已检查,然后它们将被忽略take.ms/ZYOfB
    • @Zyga 这就是 Angular 所说的变化检测take.ms/XJhmx。这是视图检查。
    • @yurzui 我认为一旦调用 ngDoCheck() 就意味着检查了组件的所有绑定(我认为这是更改检测)。 isVisible 中的 console.log 未执行,因为该值与上次运行相比没有变化。这是我的理解,尽管我可能错了:)。在我有很多项目的真实代码中,我可以看到执行这个 ngDoCheck() 实际上需要很长时间并导致性能命中,我只是认为当只有一个子组件被点击时,它不必对所有子组件执行此操作?但也许我在这里错过了一些观点......
    猜你喜欢
    • 1970-01-01
    • 2017-09-28
    • 2021-08-07
    • 2017-06-07
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    相关资源
    最近更新 更多