Angular Best Practices

While using Angular, have you come across the situation where your app experiences performance bottlenecks such as slow response of your app, or just unresponsiveness?

This could put your users at stake because they might lose their $$ the time the app gives no output properly.

This article mainly focuses key strategies to improve the performance of your Angular apps to ensure better responsiveness, faster load times and enhanced user experience.

Lazy Loading Modules

Initially the app takes more time to load as all app modules are loaded upfront. Using Angular's lazy loading feature, we can load the modules on demand.

Taking an example of FeatureModule to navigate to the /feature route.

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

This approach ensures that the FeatureModule is loaded only when the user navigates to the /feature route.

Event Listeners Disposition

When event listeners are not disposed they lead to memory leaks.

In Angular, unsubscribed observables if not destroyed/dumped lead to memory leaks.

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

@Component({
  selector: 'app-example',
  template: ``
})
export class ExampleComponent implements OnDestroy {
  private destroy$ = new Subject<void>();

  ngOnInit() {
    this.someObservable.pipe(takeUntil(this.destroy$)).subscribe(data => {
      console.log(data);
    });
  }

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

Here we have used takeUntil` operator for subscription management and the subscription is later destroyed ensuring no memory leaks occur.

Example with async Pipe:

<div *ngIf="data$ | async as data">
  {{ data }}
</div>

Use Angular Pipes for Data Transformation

Angular pipes are pure functions by default and prevent unnecessary recalculations. As a result they give optimize performance.

<p>{{ date | date: 'shortDate' }}</p>

You can also write your custom pipe

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

@Pipe({ name: 'capitalize' })
export class CapitalizePipe implements PipeTransform {
  transform(value: string): string {
    return value.charAt(0).toUpperCase() + value.slice(1);
  }
}

Preloading Modules

Angular allows to load modules in the background after the initial load.

import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: () => import('./home/home.module').then(m => m.HomeModule) },
  { path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
  exports: [RouterModule]
})
export class AppRoutingModule {}

After the initial application load, all lazy-loaded modules are preloaded in the background using PreloadAllModules strategy to improve response of the Angular web application.

Optimize Template Rendering

We can optimize our Angular app by rendering our template properly. This can be done in two ways:

a) Using *ngIf and *ngFor

We can optimize our app by avoiding unnecessary of DOM elements.

The trackBy function can be used with *ngFor to identify the items and load our list quickly.

<ul>
  <li *ngFor="let product of products; trackBy: trackByFn">{{ product.name }}</li>
</ul>

TS (component) logic

trackByFn(index: number, product: any): number {
  return product.id;
}

b) Avoid Using Complex Expressions in Templates

Complex expressions in your HTML template induces unnecessary calculations and even recalculation of the whole page during the change detection — Avoid this!

Unoptimized approach:

<h1>{{ user.firstName + ' ' + user.lastName }}</h1>

Optimized approach:

get fullName(): string {
  return `${this.user.firstName} ${this.user.lastName}`;
}

Ending Note

Optimization of any application requires good coding techniques and implementation of best practices.

I believe, implementing the above techniques you can make your web application fast and responsive, even as it scales.

Thank you for reading 😊

If you enjoyed reading, be sure to give it 50 claps! Follow and don't miss out on any of my future posts.

Buy Me A Coffee ☕

Writing from experience takes time. Writing actual piece takes more time. Therefore, if you're able, you can buy me a coffee on Buy Me a Coffee. It's a small gesture that helps us keep the lights on and continue creating content that matters to you. Thank you for considering, and for being part of our community!

Here's the link 👉 buymeacoffee.com/rohanraobhb

You can connect with me on

LinkedIn — https://www.linkedin.com/in/rohan-rao-8344a7b0/

Substrack — https://substack.com/@rohanrao2

In Plain English 🚀

Thank you for being a part of the In Plain English community! Before you go: