最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular change detection slow - Stack Overflow

programmeradmin4浏览0评论

I have a large array that I am using in a ponent (ponent A) with *ngFor with a nested *ngFor.

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 ponent B.

Component A is not a child of ponent B.

As soon as the ponent A is rendered change detection bees very slow. the array does not change and I am using the ChangeDetectionStrategy.OnPush strategy for ponent A but when I fire ref.detectChanges() inside ponent B, ngDoCheck gets called on ponent A and I can see a noticeable jank on mousemove.

Is there a way to tell angular to pletely ignore the large array of items in ponent A and allow me to handle when the UI should be updated? I thought that using ChangeDetectionStrategy.OnPush would give me what I need but I have tried removing all @Input()s from ponent A and anytime I call this.ref.detectChanges() inside ponent B it is still firing ngDoCheck and it is obvious that this is very slow.

I can scroll through the list of items no issue, but it is when I am triggering the detectChanges inside the mousemove on ponent B that is causing the issue. 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.

I have a large array that I am using in a ponent (ponent A) with *ngFor with a nested *ngFor.

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 ponent B.

Component A is not a child of ponent B.

As soon as the ponent A is rendered change detection bees very slow. the array does not change and I am using the ChangeDetectionStrategy.OnPush strategy for ponent A but when I fire ref.detectChanges() inside ponent B, ngDoCheck gets called on ponent A and I can see a noticeable jank on mousemove.

Is there a way to tell angular to pletely ignore the large array of items in ponent A and allow me to handle when the UI should be updated? I thought that using ChangeDetectionStrategy.OnPush would give me what I need but I have tried removing all @Input()s from ponent A and anytime I call this.ref.detectChanges() inside ponent B it is still firing ngDoCheck and it is obvious that this is very slow.

I can scroll through the list of items no issue, but it is when I am triggering the detectChanges inside the mousemove on ponent B that is causing the issue. 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.

Share Improve this question edited Mar 23, 2018 at 11:33 lin 18.4k4 gold badges65 silver badges87 bronze badges asked Mar 23, 2018 at 11:12 raygerrardraygerrard 84211 silver badges14 bronze badges 1
  • use 'trackBy : yourTrackByFn' in *ngFor . This will solve your issue, as whenever ChangeDetection happend it execute life cycle event for that ponent every time which impact on performance. – Amol Bhor Commented Mar 23, 2018 at 14:53
Add a ment  | 

2 Answers 2

Reset to default 4

I have got to the bottom of this issue.

The problem was that inside ponent A for the nested *ngFor I was using a child ponent 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.

I have now moved the html from the child ponent into ponent A directly and this has had a huge impact on performance.

this.ref.detach() to remove the detector from from the tree pletely, that should stop the checking. Then you can still call detectChanges to do it manually, and reattach to bring it back online.

Maybe also debouncing the mousemoves (rxjs debounceTime()) might help, unless you really need to track every mousemove?

One more optimization if you already didn't, add trackBy: yourTrackByFn to the ngFor(s).

发布评论

评论列表(0)

  1. 暂无评论