#loading

Angular Performance Tips & Tricks

Angular Performance Tips & Tricks

Apr 22, 2019

Although Angular is a fairly productive framework, it may be characterized by the possibility of performance degradation as the application grows. If the application consists of pages with a huge number of components, hundreds of calculated values and event handlers, then there will inevitably be a problem when the data update starts. This may take a significant amount of time. This article will help you solve a number of performance problems that every big project eventually faces.

Angular checks by default any modifications in all existing components on the page when there is a change to any of them.  This is also true for DOM events, while it continues to perform some built-in functions, etc. The main point you should keep in mind is that Angular always checks all the components of the page no matter how many there are of them, and its overload amount may lead to significant slowdowns.

Cache Calculated Values If They Do Not Change Often

Sometimes we use getters for calculated values. They work fine when our calculations are simple, but everything changes when we do some more complicated calculations for JavaScript items. For example, the server returns to us an ISO string with the date in the TCB, and we need to display the local time in the correct format:

@Component({
  // ...
})
class MyComponent {
  @Input() data: Data;
  
  get localTime() {
  	return this.formatDate(this.input.date);
  }
  
  private formatDate(date: string) {
  	// ... your formatting code
  }
}

As mentioned above, the framework checks pages for any changes or events and for that reason our getter code is executed each time. If we know that the data in the component rarely changes, then we can optimize this piece of code by caching:

@Component({
  // ...
})
class MyComponent {
  private _localTime: string;

  @Input() data: Data;

  get localTime() {
    if (!this._localTime) {
      this._localTime = this.formatDate(this.input.date);
    }

    return this._localTime;
  }

  private formatDate(date: string) {
    // ... your formatting code
  }
}

Now, even with frequent modification checks, we eliminate the need to calculate a complex value that is unlikely to change.

Disable Change Detection

In the case when the component has nothing to change at all, it makes sense to turn off change checking. This is possible through the built-in service ChangeDetectorRef.

@Component({
  // ...
})
class MyComponent {
  constructor(cdr: ChangeDetectorRef) {
  	cdr.detach();
  }
}

Now, Angular will completely ignore this component during the check. However, you should consider that this way the check for all nested (child) components will also be disabled. If this option does not suit you, then pay attention to the next trick.

Change Detection Strategy

The framework provides us with the ability to customize the strategy of changes identification. By default, it uses the one I’ve described at the beginning of this article, but we can easily change this behavior through the @Component decorator. Use the ChangeDetection property with the value ChangeDetectionStrategy.OnPush. This will make the framework to check the component only when its @Input value changes and it does not affect the child components.

@Component({
  // ...
  template: `<app-child [name]="name"></app-child>`
})
class ParentComponent implement OnInit {
  name = 'John Doe';
  
  ngOnInit() {
    setTimeout(() => this.name = 'Richard Roe', 5000);
  }
}


@Component({
  // ...
  selector: 'app-child'
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `{{ greeting }}, {{ firstName }} {{ lastName }}`
})
class ChildComponent implements OnInit {
  @Input() name: string;
  greeting = 'Hello';
  
  ngOnInit() {
    setTimeout(() => this.greeting = 'Salut', 2000);
  }
}

Obviously, Angular will mark this component to check changes only if the value of the name is changed. The value of the greeting will still change after two seconds; however, in UI you will see these changes only after 5 seconds. This happens when the name modifies and the framework makes checks in this component.

If you want to manually check the changes, then the already known service ChangeDetectorRef will come to your help.

ngOnInit() {
  setTimeout(() => {
    this.greeting = 'Salut';
    this.changeDetectorRef.markForCheck();
  }, 2000);
}

This method will force Angular to check the component at the right moment. Also, this will cause a check of changes in all child components. If you do not need it, use the detectChanges()  method.

Using these tricks can easily speed up your Angular application by simply getting rid of unnecessary checks where there is no need for them.

BE THE FIRST WHO GETS UPDATES
Using Corsac Blog and website you agree to our Privacy Policy and Terms and Conditions.