Sergey A
Sergey A

Reputation: 157

Angular performance - pipe vs getter

For example I have simple array with ToDo items.

[
  { name: 'Item 1', completed: false },
  { name: 'Item 2', completed: false }
  { name: 'Item 3', completed: true }
  { name: 'Item 4', completed: false }
]

This array should be displayed in 2 rows:
Done and Not Done.

I have 2 options to do it.
1 Getter.

public get doneItems() { 
    // filter and return only done items. And similar method for not done 
}

2 Pipe.

Question:
Do you have some metrics or suggestions which options has better performance, in case there should be live updated array (add, remove, update) and more complicated items and up to 100 items on page.
Thanks!

Upvotes: 3

Views: 3044

Answers (1)

Alexander Leonov
Alexander Leonov

Reputation: 4794

As @mok accented, in your case it shouldn't matter at all, but if address your question precisely... well, let's speculate a little bit.

Getter. It can be called like billion times during change detection cycle. If you implement filtering inside it then each time your getter will return new array containing the same set of objects. This will lead to a constant diff re-calculations in the ngFor directive with the same result each time. Again, for 100 items this overhead should not be measurable at all (angular team did really awesome job optimizing that thing!), but still it is a bunch of unnecessary operations. Not really best option.

Pipe. To get a good solution here you'll need to do two things: a) implement pure filtering pipe; 2) make sure that your source array is immutable, i.e. no updates can be made to this array - each and every operation on the array (add/delete/move/change items) must produce new array. This way angular will give you pretty much the best option you can have - unless you change source array or filtering value angular will take no action at all to update the view during change detection cycle. So, there can be good solution here but it requires a bit of careful and thoughtful coding.

There's also another option possible here. You can make two partial arrays - DoneArray and NotDoneArray (naming is stupid, I know, you can do better ;)) - and fill them up at the moment when you change your main array. Having that, you can make two dumb getters that would just return those arrays, and use those getters in the template. Those arrays would be immutable as long as the main array is not changed, thus not causing additional overhead with change detection. It this case you'll not need special pipe at all, just go with plain *ngFor and it will do. Downside here is twice as much memory needed to store the data, but again, for just 100 items... who cares? :)

PS. Forgot about very important thing - there are also some explanations in angular documentation which strongly suggest against using pipes in such a manner. You'll need to keep that in mind too and check whether your solution works after minification.

Upvotes: 2

Related Questions