Ad

Change Detection in Angular


    Change detection is a core concept in Angular that ensures the application's user interface remains in sync with its underlying data model. While developers rely on it daily, many are unaware of how it truly operates—or how to optimize it for performance and maintainability.
This article provides a comprehensive overview of Angular’s change detection mechanism, including how it works, when it is triggered, and how developers can take control over it when necessary.

What is Change Detection?

In simple terms:
Change detection is how Angular knows when to update the UI.

Whenever data bound to the template is updated—whether from user input, HTTP responses, or other sources—Angular evaluates whether the view should be updated.

Consider the following example:
html<!-- template -->
<p>{{ counter }}</p>
If counter changes from 1 to 2, Angular updates the <p> element and reflects the updated value. This synchronization happens automatically, but the internal mechanism is worth exploring for deeper understanding and optimization?


How Change Detection Works?

Angular’s change detection is triggered by asynchronous activities such as:
    1. User events (e.g., clicks, key presses)
    2. Timers (setTimeout, setInterval)
    3. HTTP responses
    4. Promises
    5. Manual interactions with Angular APIs

This is made possible by Zone.js, a library Angular uses to intercept asynchronous operations and notify the framework when they complete. Every time such an event occurs, Angular initiates a change detection cycle that starts at the root component and propagates down the component tree.


Change Detection Strategies

Angular provides two change detection strategies through the ChangeDetectionStrategy enum:

1. ChangeDetectionStrategy.Default
This is the default behavior. Angular checks every component in the application on each change detection cycle, regardless of whether its inputs have changed.
ts@Component({
  selector: 'app-default',
  template: `

{{ name }}

`, changeDetection: ChangeDetectionStrategy.Default, }) export class DefaultComponent { @Input() name: string; }

2. ChangeDetectionStrategy.OnPush
With OnPush, Angular limits change detection to components whose @Input() properties have changed by reference, or when an event handler is triggered within the component.
ts@Component({
  selector: 'app-on-push',
  template: `

{{ name }}

`, changeDetection: ChangeDetectionStrategy.OnPush, }) export class OnPushComponent { @Input() name: string; }

This strategy is particularly useful for improving performance in large applications or components that rely on immutable data patterns or RxJS.

 

ChangeDetectorRef

The ChangeDetectorRef class offers fine-grained control over Angular's change detection behavior. It provides several key methods:

detectChanges()
This method triggers change detection manually for the current component and its children.
Use Case Example: When working with third-party libraries or dynamically inserted views, the view may not reflect state changes until this method is invoked.
tsconstructor(private cd: ChangeDetectorRef) {}

ngAfterViewInit() {
  this.cd.detectChanges();
}

markForCheck()
In ChangeDetectionStrategy.OnPush components, if a change occurs outside Angular's detection (such as a setTimeout or WebSocket event), you can mark the component to be checked in the next cycle.
tssomeAsyncCall().then(() => {
  this.data = updatedData;
  this.cd.markForCheck();
});

detach()
and reattach()
Use detach() to exclude a component from change detection. This is particularly beneficial in performance-critical sections of the application, such as live dashboards or frequently updating charts.
tsngOnInit() {
  this.cd.detach();
}

updateManually() {
  this.cd.detectChanges(); // Manually apply changes when needed
}
Use retach() to resume automatic detection


Common Pitfalls

Mutating Arrays or Objects
Angular tracks changes by reference. Mutating an existing object or array does not trigger change detection.

ts
this.items.push(newItem); // No view update
this.items = [...this.items, newItem]; // View will update

Binding Functions in Templates
Avoid binding methods directly in templates, as they are executed on every change detection cycle.

ts

{{ calculateTotal() }}

// Inefficient
Use a property instead, or rely on Angular pipes.

Conclusion

A solid understanding of Angular’s change detection mechanism enables developers to write more predictable and performant applications. By knowing when and how Angular updates the view, and using tools such as ChangeDetectionStrategy and ChangeDetectorRef, developers can avoid common pitfalls and fine-tune application responsiveness.
In a future article, we will explore Zone-less Angular—a more advanced topic with growing importance in Angular's evolving ecosystem.