user1108011
user1108011

Reputation: 21

The most optimized way to bind variables in Angular when dealing with objects

I read the manual of binding object properties in Angular, however I struggle to find the perfect most optimized solution.

Let's say i have a model User

export class User {
  public _id: number;
  public _firstName: string;
  public _lastName: string;
  public _active: boolean;
  public _type: string;

  constructor(id: number, firstName: string, lastName: string, type: string, active: boolean = true) {
    this._id = id;
    this._firstName = firstName;
    this._lastName = lastName;
    this._active = active;
    this._type = type;
  }
}

I want to display ID, firstName and LastName if the user is active and of certain type - let's say administrator. Pretty simple, right?

From what I've read the easiest solution is:

<span *ngIf="model._active && model._type === 'administrator'">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

You can even pipe this:

<span *ngIf="model._active | isModelActive : model._type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model._type}}</span>

Pipe gets called only once on init, and each time if property "active" changes. Changing the property "id" doesn't call the pipe.

In reality however your models most likely have private fields with accessors, since you want to encapsulate your objects. Now this is when this goes badly really quick.

private _active: boolean;
get active(): boolean {
   console.log('get active');
   return this._active;
}

now binding the getter instead of field causes this function to be called multiple times, plus it also gets called when other properties are changed (like id for example). God forbid if you have (mouseover) somewhere else because it will constantly redraw the view.

You can also pipe this:

<span *ngIf="model.active | isModelActive : model.type">{{model._id}} | {{model._firstName}} | {{model._lastName}} | {{model.type}}</span>

But still changing the property "id" causes the redraw. And if you want to pass the object to the pipe, you have to declare it impure, which according to documentation can cause serious performance degradation.

So which solution is the best? Or maybe there is another one I don't know about. Lemme know.

Upvotes: 0

Views: 30

Answers (1)

Petr Averyanov
Petr Averyanov

Reputation: 9486

  1. Using get method is not slower than field ref, so this should not bother u. If while mouseover this get method will return same result, view wont be redrawn.
  2. Pipe. Pure pipe wont run when you change id, but it will check that pipe inputs did not change each digest cycle. So it wont be faster than ngIf

You should not focus on things above in 99.9999% of cases -- you will never get any measurable performance improvement.

  1. ChangeDetectionStrategy. This is what you missed. If you care about performance you should use ChangeDetectionStrategy.OnPush. E.g. with onPush get-methods, pipes etc. will be called less frequently.

Upvotes: 0

Related Questions