Angular is an open-source front-end framework developed by google which is a complete rewrite of Angular JS. To know more about Angular, I have written an detailed blog on Introduction to Angular, where you can get more idea on it.

There are certain things that we’ll code now, and we will justify it that we can refactor it later. Sometimes it may be a huge performance issue that we may not notice. So, in this blog, we are going to explore about those kind of issues and we will see how we can solve it.

#1 Don’t use Functions in Angular Templates

Basically, Angular will consists of HTML, styling sheets and typescript files. Sometimes, we’ll call a function directly from HTML which is not good. Let’s take an example,

app.component.ts

import { Component } from '@angular/core'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent { name = 'Angular'; print(){ console.log("Hello World!") } }

We have an function called print() which is going to print Hello World in the respective console.

app.component.html

<h2>Angular Application</h2> {{print()}}

There are situations where we will call function directly from the Angular templates. If you run this application, in the console you can see some weird things happening such as printing Hello World more than once which is not good.

Imagine in an large enterprise application, if that respective function does some complex operation then it will be executed more than once.

Why does this happen?

This is because of the change detection mechanism of Angular. Angular cannot detect whether the result of print() is changed until it runs the print() function.

It does not maintain the state of the respective function whether it has been already executed or not.

How we are going to solve it?

If you want to overcome this problem, you can use Angular Pipes. Basically, a pipe is a generic function which takes an input and provides you the desired output. To get more understanding on Angular Pipes, please visit this link.

We are going to create a pipe which does the same operation.

print.pipe.ts

import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'printPipe' }) export class PrintPipe implements PipeTransform { transform(value: any): any { let joinedString = value + " Hello World!"; console.log(joinedString); return joinedString; } }

In this pipe, it gets the input and concatenate the string with Hello World and we are just returning the concatenated string.

app.component.html

{{ "Welcome!" | printPipe}}

In the console, you can see only one Welcome! Hello World!. There won’t be multiple logs. That’s the power of Angular Pipes as it maintains the state.

#2 Lazy Loading Modules

In a large enterprise application, there would be lot of pages involved. Basically, in angular we have an concept called Module. Let’s take an example, think if your application contains a login page and a dashboard page. We can have separate modules for it, say Login Module and Dashboard Module.

The main purpose of Lazy Loading is to load modules which is necessary at the right time. During the login page, I don’t need the Dashboard module to be loaded, I just need the Login Module. So, using Lazy Loading I can load respective modules at the respective page.

You must do Lazy Loading in your Respective Routes.

Before Lazy Loading

const routes: Routes = [ { path: '', component: LoginComponent }, { path: 'dashboard', component: DashboardComponent } ];

After Lazy Loading

const routes: Routes = [ { path: '', component: LoginComponent }, { path: 'login', loadChildren: './dashboard/dashboard.module#DashboardModule' } ];

Note: From angular 8 you need to do lazy loading as,

const routes: Routes = [ { path: '', component: LoginComponent }, { path: 'login', loadChildren: () => import('./dashboard/dashboard.module#DashboardModule') .then(applicationRoute => applicationRoute.DashboardModule) } ];

#3 AOT Compilation

If you want to do a production build in angular, you can make use of the below command.

ng build --prod

When you run this command, Angular uses JIT (Just in Time) Compilation technique, which essentially means, Angular compiles your views into the browser at runtime. There are some cons of using this technique such as,

The compilation process should be run before you can use it and also this can increase the loading time of your respective site.

You must ship the Angular Compiler with the module, which is not a small module.

So, to improve the performance of your respective application, you can make use of AOT Compilation.

ng build --aot

AOT (Ahead of Time) Compilation can be used to build the respective files before the browser downloads and runs that code. Compiling your application during the build process provides a faster rendering to your browser.

Note: From angular 8, the prod build by default it does AOT Compilation instead of JIT.

#4 Unsubscribe

Most of the Angular applications will consists of RxJS. It is a library for reactive programming using Observables to make it easier to compose asynchronous or callback-based code. If it’s an large enterprise application, we will use lot of observables if we want to make any HTTP Requests.

Observables are awesome but you need to unsubscribe it once the operation has been completed. If you don’t unsubscribe, it may lead to memory leak and this may cause a performance issue.

export class AppComponent implements OnDestroy { private subscription: Subscription; constructor(router: Router) { this.subscription = this._service.init().subscribe(event => { // do operations }); } ngOnDestroy(): void { this.subscription.unsubscribe(); } }

#5 Async Pipe

Angular Pipes are one of most awesome utility. There are lot of predefined pipes in angular which you can make use of in your respective application. Async Pipe allows you to use RxJS Observables directly in your respective Angular Templates.

But as we saw earlier, if you subscribe to an observable make sure you unsubscribe it. But if you use async pipe you don’t have to worry about it. The best use of Async Pipe is that it allows us to use OnPush Change Detection.

Whenever the value of an observable gets changed, we can inform Angular about it and the async pipe takes care of updating the current value. You can use Async pipe as,

<p>{{sampeObservable | async}}</p>

As I said previously you don’t have to worry about unsubscribing the respective observable. It’s one of my favorite pipe in Angular.

#6 *ngFor using TrackBy

In Angular, *ngFor is a conditional directive which can be used to iterate the respective arrays and make some operations based upon the values obtained.

When a web page is loaded, the browser creates a Document Object Model(DOM). And this DOM should not manipulated much, because it will impact the performance of your application. And when you use *ngFor there are some chances where your DOM gets manipulated.

So how we can avoid it? Visit this link, to get an clear description of this issue.

Conclusion

These are some of the performance improvements that can be taken into consideration whenever you build an angular application. It’s the responsibility of the developer to take care of the performance of the respective application.

As you know, Performance is a large topic in Angular but in this blog we have covered most of the performance improvements that can be done in an angular application.

Hopefully you’ll get something out of it from this blog.

Happy Coding!

Cheers! 🙂