4

I would like to ask about *ngIf binding to function return value. Will it have performance overhead when comparing *ngIf binding to property.

This is only sample code for asking concept, the data structure is complex than that in DataService. The enable flag will be saved in a map object. This is just a simple expression:

In typescript service

export class DataService() {
   private enable: boolean;

   isEnable() {
      return enable;
   }

   getEnableValue() {
      return enable;
   }

   update(flag: boolean) {
      enable = flag;
   }
}

In html,

<div *ngIf="isEnable()">
    <p> {{ testObject.value }}</p>
</div>

In typescript,

isEnable() {
   return this.dataService.isEnable();
}

vs

In html,

<div *ngIf="isEnable">
    <p> {{ testObject.value }}</p>
</div>

In typescript,

isEnable: boolean;
ngOnInit() {
    isEnable = this.dataService.getEnableValue()
}

For *ngIf="isEnable", I am able to understand。 But for function binding,is angular check the property in the function and monitor it changes? Any performance difference?

Thanks a lot.

9
  • Add console.log("hello") to your function, and you'll know. It's called at each change detection, to know if the element should be added or removed from the DOM. Commented Aug 3, 2018 at 13:53
  • It will have performance difference depending on the complexity of your function. If you just have a property binding, then it is just checking that property.If you have a function that loops through, say, 3,000 items in an array, then that loop will run every single time a change detection is triggered. So yes, performance wise, a property variable is better. Commented Aug 3, 2018 at 13:58
  • I know *ngIf is to add or remove from the DOM. May be my question is not clear. I would like to ask is that the value changes in function and the value changes in property that assign to *ngIf, does it impact on performance for 2 different style writing? Commented Aug 3, 2018 at 13:58
  • It depends on what this.dataService.isEnable() has to do before returning the value. Commented Aug 3, 2018 at 14:23
  • 1
    Angular will have to reevaluate the function to know if it has changed. I would use a Subject or BehaviourSubject to avoid that. Commented Aug 3, 2018 at 15:18

1 Answer 1

3

Technically speaking there is no noticeable difference in performance.

When Angular compiles AOT templates they are converted into JavaScript source code, and all those one-way bindings are turned into functions.

So I there shouldn't be any noticeable performance when doing any of the following.

export class MyComponent {
     public title1: string;

     public get title2(): stirng {
          return this.title1;
     }

     public getTitle3(): string {
          return this.title1;
     }
}

Use all 3 above would have about the same performance.

Downsides

There are side effects to using functions.

  • it breaks the dry principle of a template
  • you can not see how complex a template is
  • performance is hidden inside functions

I've also found that you tend to do more work in the template. When you call functions it makes it easier to use *ngIf, *ngFor and other logical components.

When you read the source code for the component you don't get the full picture. There is a lot of the business logic being done in the template, and when you read the template you don't see how it will be viewed, because there is a lot logic in the template.

Sign up to request clarification or add additional context in comments.

4 Comments

If the isEnable() in DataService has to access the map and retrieve its value: const object = map.get('type1'); return object.enable. Will every map content changes trigger evaluate function?
@rodent_la You're confusing performance and change detection. The two are different topics. If you are using OnPush (which you should be) then any changes in the services will not trigger template rendering, because you should be pushing data to the templates.
Thank you so much.
Indeed there is a performance impact! When you use a function instead of a immutable or primitive data type (boolean, string, number) angular has to evaluate the function each application tick / change tracking tick! That's the worst you can do! Use observables (rxjs) or pre-evaluate the state and persist it within a public accessible property to bind on the template! Reference: stackoverflow.com/questions/49320756/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.