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>