
Change detection is triggered too frequently, affecting performance.
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
})
export class MyComponent {
@Input() data: any;
}
Use the OnPush strategy in components where possible. This makes change detection occur only when the component's input changes.
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {
@Input() data: any;
}
Direct DOM manipulations can be inefficient and hard to manage.
ngAfterViewInit() {
document.getElementById('elementId').style.color = 'blue';
}
Use Angular’s Renderer2 to manipulate the DOM more efficiently.
import { Renderer2 } from '@angular/core';
constructor(private renderer: Renderer2) {}
ngAfterViewInit() {
const element = this.renderer.selectRootElement('#elementId');
this.renderer.setStyle(element, 'color', 'blue');
}
Pipes that perform heavy operations can be re-executed frequently, hurting performance.
@Pipe({
name: 'heavyPipe',
pure: false
})
export class HeavyPipe implements PipeTransform {
transform(value: any): any {
// Heavy transformation logic
}
}
Use pure pipes (pure: true) for lightweight operations or avoid pipes for heavy operations.
@Pipe({
name: 'heavyPipe',
pure: true
})
export class HeavyPipe implements PipeTransform {
transform(value: any): any {
// Light transformation logic
}
}
Loading all modules and components at initialization can delay loading time.
@NgModule({
declarations: [AppComponent, FeatureComponent],
imports: [BrowserModule, FeatureModule],
bootstrap: [AppComponent]
})
export class AppModule {}
Use lazy loading for modules that are not immediately needed.
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
Not cancelling subscriptions can lead to memory leaks.
ngOnInit() {
this.myService.myObservable.subscribe(value => {
// Do something with value
});
}
Use the async pipe or manage subscriptions with takeUntil or Subscription.
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnDestroy {
private destroy$ = new Subject<void>();
constructor(private myService: MyService) {
this.myService.getData()
.pipe(takeUntil(this.destroy$))
.subscribe(data => {
// Handle the data
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
For Angular 16+ use takeUntilDestroyed.
import { Component, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit, OnDestroy {
constructor(private myService: MyService) {
}
ngOnInit(): void {
this.myService.getData()
.pipe(takeUntilDestroyed(this))
.subscribe(data => {
// Handle the data
});
}
ngOnDestroy() {
}
}