【问题标题】:Angular change detection slow角度变化检测慢
【发布时间】:2018-03-23 11:12:51
【问题描述】:

我有一个大型数组,我在一个组件(组件 A)中使用 *ngFor 和一个嵌套的 *ngFor

组件 B 初始化一个 jquery 插件,该插件注册了一个文档 mousemove 事件处理程序,我使用 this.zone.runOutsideAngular 来初始化插件,我在回调中调用 this.ref.detectChanges(),因为我需要更新 mousemove 上的 UI在组件 B 中。

组件 A 不是组件 B 的子组件。

一旦组件 A 被渲染,变更检测就会变得非常缓慢。数组没有改变,我对组件 A 使用 ChangeDetectionStrategy.OnPush 策略,但是当我在组件 B 内触发 ref.detectChanges() 时,ngDoCheck 在组件 A 上被调用,我可以在 mousemove 上看到明显的卡顿。

有没有办法告诉 Angular 完全忽略组件 A 中的大量项目并允许我处理何时应该更新 UI?我认为使用ChangeDetectionStrategy.OnPush 可以满足我的需要,但我已经尝试从组件A 中删除所有@Input()s,并且无论何时我在组件B 中调用this.ref.detectChanges(),它仍在触发ngDoCheck,很明显这是很慢。

我可以滚动浏览项目列表没有问题,但是当我触发组件 B 上的 mousemove 内的 detectChanges 时,会导致问题。我知道我可以手动更新 DOM,但我认为这只是一种解决方法,因为它只会解决 mousemove 上的卡顿问题,而不是围绕更改检测缓慢的问题。

【问题讨论】:

  • 在 *ngFor 中使用 'trackBy : yourTrackByFn'。这将解决您的问题,因为每当发生 ChangeDetection 时,它每次都会为该组件执行生命周期事件,这会影响性能。

标签: javascript angular ngzone


【解决方案1】:

我已经深入了解了这个问题。

问题在于,在嵌套 *ngFor 的组件 A 内部,我使用子组件来呈现每个子项,这意味着尽管我使用了 ChangeDetectionStrategy.OnPush 策略,但它仍然需要对每个项进行 ref 检查。

我现在已经将 html 从子组件直接移动到组件 A 中,这对性能产生了巨大影响。

【讨论】:

    【解决方案2】:

    this.ref.detach() 将检测器从树中完全移除,这应该会停止检查。然后您仍然可以致电detectChanges 手动执行此操作,并致电reattach 将其重新上线。

    也许还可以消除鼠标移动的抖动 (rxjs debounceTime()) 可能会有所帮助,除非您真的需要跟踪每个鼠标移动?

    如果您还没有进行进一步优化,请将 trackBy: yourTrackByFn 添加到 ngFor(s)。

    【讨论】:

    • 感谢您的回答。我忘了提到我尝试过分离,但没有帮助。
    猜你喜欢
    • 2021-06-17
    • 2021-08-07
    • 2018-10-24
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多