Skip to content

Angular Performance Tips

Angular is a powerful framework for building web applications, but like any framework, it can suffer from performance issues if not used correctly.

Here are some tips for improving the performance of Angular applications:

Change Detection Strategy

Angular uses change detection to update the view when the application state changes. By default, Angular uses the ChangeDetectionStrategy.Default strategy, which checks the entire component tree for changes on every change detection cycle.

To improve performance, you can change the change detection strategy of a component to ChangeDetectionStrategy.OnPush. This strategy only checks a component for changes if its input properties have changed or if an event has been triggered. This can significantly reduce the number of change detection cycles and improve performance.

import { Component, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {
  // Component logic
}

Lazy Loading

Lazy loading is a technique that defers the loading of non-essential resources until they are needed. In an Angular application, you can use lazy loading to load modules, components, or routes only when they are required, reducing the initial load time of the application.

To lazy load a module in Angular, you can use the loadChildren property in the route configuration:

const routes: Routes = [
    { path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule) }
];

AOT Compilation

Ahead-of-Time (AOT) compilation is a technique that compiles Angular templates and components during the build process, rather than at runtime. This can improve the performance of an Angular application by reducing the size of the bundle and speeding up the initial load time.

To enable AOT compilation in an Angular application, you can use the --aot flag when running the build command:

ng build --aot

Tree Shaking

Tree shaking is a technique that removes unused code from the application bundle during the build process. This can reduce the size of the bundle and improve the performance of the application.

To enable tree shaking in an Angular application, you can use the --prod flag when running the build command:

ng build --prod

Use Pure Pipes

Angular pipes are used to transform data in the template. By default, Angular pipes are impure, meaning they are re-evaluated on every change detection cycle, even if the input has not changed.

To improve performance, you can use pure pipes, which are only re-evaluated if the input has changed. To create a pure pipe in Angular, you can set the pure property to true in the pipe decorator:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'myPipe',
  pure: true
})
export class MyPipe implements PipeTransform {
  transform(value: any, ...args: any[]): any {
    // Pipe logic
  }
}

Use TrackBy Function

When rendering lists in Angular, it is important to provide a trackBy function to help Angular identify items in the list and improve performance. The trackBy function should return a unique identifier for each item in the list.

<ul>
  <li *ngFor="let item of items; trackBy: trackByFn">
    {{ item.name }}
  </li>
</ul>
trackByFn(index: number, item: any): number {
  return item.id;
}

Unsubscribe from Observables

When subscribing to Observables in Angular, it is important to unsubscribe from them when they are no longer needed to prevent memory leaks. You can use the takeUntil operator to automatically unsubscribe from an Observable when a component is destroyed.

import { Component, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';


@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html'
})

export class MyComponent implements OnDestroy {
  private destroy$: Subject<void> = new Subject<void>();

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  ngOnInit(): void {
    this.myService.getData()
      .pipe(takeUntil(this.destroy$))
      .subscribe(data => {
        // Handle data
      });
  }
}

Avoid complex computations in the template

Avoid complex computations in the template, as they can slow down the rendering process.

Instead, move the computation logic to the component class and store the result in a variable that can be accessed in the template.

<!-- Bad -->
<div>{{ complexCalculation() }}</div>


<!-- Good -->
<div>{{ data$ | async }}</div>

Virtual Scrolling

Virtual scrolling is a technique that only renders the items that are visible in the viewport, rather than rendering the entire list.

In Angular, you can use the cdk-virtual-scroll-viewport directive from the Angular CDK to implement virtual scrolling:

import { ScrollingModule } from '@angular/cdk/scrolling';

<cdk-virtual-scroll-viewport itemSize="50">
  <div *cdkVirtualFor="let item of items">{{item}}</div>
</cdk-virtual-scroll-viewport>