Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular - What is the point of implementing trackBy?

Since recently, the Angular styleguide-lint-extender "Codelyzer" is throwing warnings when you do not have a trackBy-function implemented on every *ngFor. I am wondering why this is considered an issue at all.

  • In this blog the example of implementing trackBy comes down to trackByFn(index, item) { return index;} // or item.id. If I switched from index to item.id, how would this make my app faster? when it comes to array insertions or deletions, index is the most straightforward thing that matters. Why should the [ngFor]-directive compare object identity values instead?
  • in the module ng_for_of.d.ts I can find _trackByFn. So I assume, a return index-trackBy is the default configuration anyway? Then why is it considered a good practice to implement it explicitly?

Now personally, I do have a big collection (array) in my app, and it lies in a redux store. It can only be replaced by an empty array or new items can get added to it, eg:

return {...state, myArray: [...state.myArray, ...newItems]}),

but never moved or deleted. Would it make sense for me to track by item.id instead of index? Should I really implement a return index;-function in every component with an *ngFor?

like image 976
Phil Avatar asked Dec 16 '17 08:12

Phil


People also ask

Why do we use trackBy in Angular?

Angular came up with the trackBy directive, which is optionally passed into ngFor to help identify unique items in our arrays. TrackBy and ngFor together allow Angular to detect the specific node element that needs to change or be added instead of rebuilding the whole array.

Is trackBy necessary?

The use of trackBy it's a performance optimization and is usually not needed by default, it's in principle only needed if running into performance issues.

Does trackBy improve performance?

Angular Trackby option improves the Performance of the ngFor if the collection has a large no of items and keeps changing. Learn why we need it and how to use it to improve the performance of the ngFor .

What is ngFor trackBy?

The angular ngFor trackBy is used to improve the performance of an angular application. At the. end of this blog, you will understand how to use ngFor trackBy and when to use the ngFor trackBy in your angular application.


1 Answers

*ngFor tracks the items by object identity and tries to avoid re-render of elements when the iterated array is updated for items in the array that where in the array already before the update.

If the array contains primitive values (string, boolean, number), then *ngFor can't identify them after they were modified.

An *ngFor over a list of strings like

items = ['foo', 'bar', 'baz'];
<input *ngFor="let item of items" [(ngModel)]="item">

would cause weired behavior when the value is modified in the rendered <input> because after each keyboard input the value would change and *ngFor would loose track where the item was rendered before and therefore remove the input for the value before the change and add it for the value after the change. This causes the input to lose focus and can cause the input to change position.

To fix this you can instruct *ngFor to track by index instead of by identity.

See also

  • *ngFor Behaviour on primitive data type
  • Angular2 NgFor inside tree model: wrong order when remove and then add elements

Also for objects it can be useful, for example if you want *ngFor to track items by an id property. This is useful for example if immutable values are used and an item of the list was modified - which means replaced by a new object instance with the same value for the id property, but some other properties changed. Instructing *ngFor to track by id doesn't cause the item to be removed and re-added to the DOM.

*ngFor not properly recognizing modified items would also cause animations like shown in this Plunker example (from How can I animate *ngFor in angular 2?) to break (animated too often).

like image 105
Günter Zöchbauer Avatar answered Sep 19 '22 18:09

Günter Zöchbauer