Does ngFor directive re-render whole array on every mutation?

admax picture admax · Feb 15, 2017 · Viewed 9.3k times · Source

Let's say we have an array of items:

items = [
    { title: 'item 1'},
    { title: 'item 2'},
    /* ... */
];

And there is a template that renders this array:

<ul>
    <li *ngFor="let item of items">{{item.title}}</li>
</ul>

Wll angular2 rerender the whole array if I add/remove items via push/splice or will it only add/remove the markup for the corresponding items? If it does updates only, then is there any difference in mutation stategies -- should I prefer push/splice over array replacing? In other words, are these two approaches equivalent in term of rendering performance:

/* 1: mutation */
this.items.push({ title: 'New Item' });

/* 2: replacement */
var newArray = this.items.slice();
newArray.push({ title: 'New Item' });

this.items = newArray;

Answer

maxime1992 picture maxime1992 · Feb 15, 2017

In addition to Gunter's answer, if you want to know which part of your UI is rendered/re-rendered you can with Chrome (even independent from any lib/framework) :

  • Open your debug panel
  • Menu (of debug panel) / More tools / Rendering

You should then see the following panel :

enter image description here

Toggle the Paint Flashing option on, and have some fun with your list.
If an area is flashing green, it has been painted / re-painted 👍.

EX : If you take the Plunkr in Gunter's answer : http://plnkr.co/edit/oNm5d4KwUjLpmmu4IM2K?p=preview and toggle the Paint Flashing on, add an item to the list and you'll see that previous items do not flash. (which means there's no repaint).