简体   繁体   English

角度变化检测缓慢

[英]Angular change detection slow

I have a large array that I am using in a component (component A) with *ngFor with a nested *ngFor . 我有一个大型数组,正在使用带有嵌套*ngFor *ngFor的组件(组件A)。

Component B initialises a jquery plugin which registers a document mousemove event handler, I am using this.zone.runOutsideAngular to init the plugin and I am calling this.ref.detectChanges() in the callback as I need to update the UI on mousemove inside the component B. 组件B初始化了一个注册了文档mousemove事件处理程序的jquery插件,我正在使用this.zone.runOutsideAngular来初始化该插件,并且在回调中调用this.ref.detectChanges() ,因为我需要在mousemove内部更新UI成分B。

Component A is not a child of component B. 组件A不是组件B的子代。

As soon as the component A is rendered change detection becomes very slow. 一旦提供了组件A,更改检测就会变得非常缓慢。 the array does not change and I am using the ChangeDetectionStrategy.OnPush strategy for component A but when I fire ref.detectChanges() inside component B, ngDoCheck gets called on component A and I can see a noticeable jank on mousemove . 数组不会改变,我现在用的是ChangeDetectionStrategy.OnPush对于组分A的策略,但是当我火ref.detectChanges() B组分内, ngDoCheck被称为组分A,我可以看到一个明显的JANK mousemove

Is there a way to tell angular to completely ignore the large array of items in component A and allow me to handle when the UI should be updated? 有没有一种方法可以告诉angular完全忽略组件A中的大量项目,并让我处理何时应更新UI? I thought that using ChangeDetectionStrategy.OnPush would give me what I need but I have tried removing all @Input() s from component A and anytime I call this.ref.detectChanges() inside component B it is still firing ngDoCheck and it is obvious that this is very slow. 我以为使用ChangeDetectionStrategy.OnPush会给我我需要的东西,但是我尝试从组件A中删除所有@Input() ,并且this.ref.detectChanges()在组件B中调用this.ref.detectChanges()它仍然会触发ngDoCheck ,这很明显这很慢。

I can scroll through the list of items no issue, but it is when I am triggering the detectChanges inside the mousemove on component B that is causing the issue. 我可以滚动浏览项目列表,没有问题,但是正是当我在组件B上的mousemove内触发detectChanges引起问题。 I know I could manually update the DOM but I think this would just be a workaround as it would only address the jank on mousemove and not the issue around the change detection being slow. 我知道我可以手动更新DOM,但是我认为这只是一个解决方法,因为它只能解决mousemove上的问题,而不会解决更改检测缓慢的问题。

this.ref.detach() to remove the detector from from the tree completely, that should stop the checking. this.ref.detach()可以从树中完全删除检测器,这应该停止检查。 Then you can still call detectChanges to do it manually, and reattach to bring it back online. 然后,您仍然可以调用detectChanges手动进行操作,然后reattach使其重新联机。

Maybe also debouncing the mousemoves (rxjs debounceTime()) might help, unless you really need to track every mousemove? 除非您确实需要跟踪每个mousemove,否则也许还要对mousemoves(rxjs debounceTime())进行反跳操作可能会有所帮助?

One more optimization if you already didn't, add trackBy: yourTrackByFn to the ngFor(s). 如果还没有进行trackBy: yourTrackByFn一种优化,则将trackBy: yourTrackByFn添加到ngFor。

I have got to the bottom of this issue. 我已经深究了这个问题。

The problem was that inside component A for the nested *ngFor I was using a child component to render each sub item which meant that although I was using the ChangeDetectionStrategy.OnPush strategy, it still required a ref check for each item. 问题在于,嵌套的* ngFor组件A内部使用的是子组件来渲染每个子项,这意味着尽管我使用的是ChangeDetectionStrategy.OnPush策略,但仍需要对每个项进行引用检查。

I have now moved the html from the child component into component A directly and this has had a huge impact on performance. 我现在将html从子组件直接移到了组件A中,这对性能产生了巨大影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM