4

Let's say I have 100 divs on my screen generated by *ngFor that takes values from my object that has data like

{A1: someObject, A2: someOtherObject..., J10: someOtherOtherObject}

I click on A1 and then on J10 and they switch their values. It changed to this:

{A1: someOtherOtherObject, A2: someOtherObject..., J10: someObject}

How do I force Angular to only refresh two divs only holding A1 and J10 values? I am using ChangeDetectionStrategy.OnPush, in constructor I have cd.detach() and only call cd.detectChanges() whenever second click occurs. Judging from what I see and am able to understand, each div triggers their *ngIf so every single one of them is recreated.

Is there anything I can do to either a) override what is being refreshed or b) choose what to detect changes against?

enter image description here

Andrius Naruševičius
  • 8,348
  • 7
  • 49
  • 78

1 Answers1

6

If you track the items in your list, *ngFor="let item of items; trackBy: trackById". Then it will not render all the items again.

trackById = trackBy('id');

...

export function trackBy(field: string): (_index: number, item: any) => string | number {
  return (_index: number, item: any) => {
    if (!item) {
      return null;
    }
    return item[field] as (string | number);
  };
}
Wandrille
  • 6,267
  • 3
  • 20
  • 43
  • This just increated the speed *dramatically*. I was aware of this function but had no experience with it before so it didn't come to mind. So nice to use my app now! Thanks a lot for an almost instant answer! – Andrius Naruševičius Nov 20 '19 at 19:44
  • 1
    Take a look at this page: [angular-performance-checklist](https://github.com/mgechev/angular-performance-checklist). You can learn a lot about angular performance improvement – Wandrille Nov 20 '19 at 19:46