3

After experiencing some in-browser sluggishness, I'm trying to optimize change detection in my Angularfire-powered app. I read this SO answer and tried to model my list code similarly.

my container class:

<section *ngIf="inclusions$ | async as standardList">
  <bl-list-item *ngFor="let standard of standardList; 
                trackBy: identify" [inclusion]="standard">
  </bl-list-item>
</section>


NOTE: inclusions$ is an Oberservable<any[]> from Angularfire's Firestore.

trackBy function:

identify(index, item) {
  return item.id;
}

presentational component:

@Component({
  selector: 'bl-list-item',
  ...
  changeDetection: ChangeDetectionStrategy.OnPush
})

The problem: ngOnChanges is invoked for all instances of bl-list-item, whenever the data for a single associated doc gets updated in Firestore. For example, if I make an edit to an Item-Doc in the Firestore web console, all bl-list-item instances fire ngOnChanges, not just the item affected by the changes.

How do I correctly configure the list-item component so that ngOnChanges only fires in affected items?

Brian A Bird
  • 378
  • 2
  • 18

2 Answers2

0

That ngOnChanges gets called is on purpose. With the change detection onPush you change the behaviour WHEN a components view is updated. If the view is now updated for a component for whatever reason, always the ngOnChanges hook of all CHILD components is called.

In your case, the container component runs change detection and calls the ngOnChanges hook for your list item components. Changing the change detection strategy of the list item components has nothing to do with that.

Gerros
  • 688
  • 11
  • 20
-1

You can try to use stateChanges(['added']) to avoid unnecessary updates as shown in the documentation.

Rodrigo Mata
  • 1,779
  • 2
  • 14
  • 23