fscheidl
fscheidl

Reputation: 2301

Performance implications of binding to simple fields vs. properties of objects vs. getters in Angular

Is there any difference in performance when binding to simple fields (e.g. [(ngModel)]="room") in comparison to binding to properties of objects? (e.g. [(ngModel)]="lesson.room") If yes, why is that?

Concerning getters: Am I correct in my understanding that binding to getters/setters and e.g. one-way binding to functions is bad, because the function will be called every single detection cycle, without Angular being able to differentiate between situations where there was no change and situations where a change actually happened and an update of the view is in fact necessary? This should make getters the least performant option in this regard.

Upvotes: 2

Views: 2951

Answers (2)

Estus Flask
Estus Flask

Reputation: 223104

There should be no difference in performance, at least until lesson reference is changed. Even then the difference will be nonexistent because property access is very fast in JavaScript. It should be noticed that room is a property too.

If accessor method or property getter is bound, it will be called on every change detection cycle. It may be appropriate if function call isn't costly and/or change detection cycles aren't too dense. If they are dense, their amount can be reduced with OnPush change detection strategy.

For example, {{ foobar }} binding is ok:

get foobar() {
  return this.foo + this.bar;
}

And {{ factorial(num) }} binding may be costly, it can be refactored to pure pipe or be cached to a property on num change.

It should be noticed that there may be some caveats, e.g. property getter will suffer performance penalty in Chrome/V8 if it isn't defined on a prototype, like:

lesson = { get room() {/*...*/} }

Depending on real performance impact, these concerns may be considered preliminary optimization.

Upvotes: 5

Günter Zöchbauer
Günter Zöchbauer

Reputation: 658067

There is a slight difference between

[(ngModel)]="room"

and

[(ngModel)]="lesson.room")

because in the former case change detection checks only if room is identical to the instance when it last checked and in the later case it has to check lession and then room.

If lession is an object and room a normal property this won't really matter because such checks are extremely fast.

Function invocation is less performant than simple object idendity comparison, but it's not too bad. It depends how often change detection happens. The most important parts are

  • that the function returns the same value on subsequent calls (if there was no async execution in between) otherwise Angular recognizes this and throws the infamous "The expression has changed since it was last checked"

  • that the function doesn't do expensive work by itself.

If these criterias are considered binding to functions is acceptable in some situations. It's just prone to get it wrong and therefore it's usually better to not use it until you fully understand how change detection works.

The best way to find out if it works for you is to create your own benchmarks for your concrete use case.

Upvotes: 1

Related Questions