Angular Components Created: 06 Jan 2026 Updated: 06 Jan 2026

Change Detection

In Angular, Change Detection is the process that keeps your UI in sync with your data. When a variable in your TypeScript changes, Angular needs to know when and how to update the HTML.

By default, Angular is very "protective"—it checks your components frequently to ensure the UI is never out of sync. However, for high-performance applications, you might want more control.

1. How Change Detection Works (The "Magic" of Zone.js)

Angular uses a library called Zone.js. It "monkey-patches" (intercepts) all asynchronous events in the browser, such as:

  1. User Events: Clicks, typing, scrolling.
  2. Timers: setTimeout(), setInterval().
  3. Network Requests: fetch() or HttpClient calls.

Whenever one of these happens, Angular assumes something might have changed in your data, so it scans your component tree from top to bottom to update the view.

2. The Two Strategies

You can define how a component reacts to these changes using the changeDetection property in the @Component decorator.

A. Default Strategy (ChangeDetectionStrategy.Default)

This is the "always-on" mode. Even if a change happens in a different part of the app, Angular will check this component to be safe. It is easy to use but can be slow if you have thousands of components.

B. OnPush Strategy (ChangeDetectionStrategy.OnPush)

This is the "performance" mode. Angular will skip checking this component and its children unless:

  1. An Input property reference changes.
  2. An Event (like a click) originates from within the component.
  3. You manually tell Angular to check (using ChangeDetectorRef).

3. Step-by-Step Example: Server Monitor

Let's build a Server Metrics Card that uses OnPush to stay performant.

Step 1: The Data Model

We use an object to represent our server.

export interface ServerMetrics {
id: string;
uptime: number;
}

Step 2: The Optimized Child Component

We set the strategy to OnPush. This means if we just change a number inside an existing object, the UI won't update. We must provide a new object reference.

src/app/server-card/server-card.component.ts

import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
import { ServerMetrics } from '../models/server.model';

@Component({
selector: 'app-server-card',
standalone: true,
template: `
<div class="card">
<h3>Server: {{ data.id }}</h3>
<p>Uptime: {{ data.uptime }} mins</p>
</div>
`,
// Optimization starts here
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ServerCardComponent {
@Input() data!: ServerMetrics;
}

Step 3: The Parent Component (The Logic)

Notice the difference between mutating data and replacing data.

src/app/dashboard/dashboard.component.ts

@Component({
selector: 'app-dashboard',
standalone: true,
imports: [ServerCardComponent],
template: `
<app-server-card [data]="myServer"></app-server-card>
<button (click)="wrongWay()">Wrong Update (No UI change)</button>
<button (click)="rightWay()">Right Update (UI updates)</button>
`
})
export class DashboardComponent {
myServer: ServerMetrics = { id: 'Web-01', uptime: 100 };

wrongWay() {
// This mutates the object.
// OnPush component will NOT see this change.
this.myServer.uptime += 1;
}

rightWay() {
// This creates a NEW object reference.
// OnPush component detects the new reference and updates!
this.myServer = {
...this.myServer,
uptime: this.myServer.uptime + 1
};
}
}

4. Why Use OnPush?

  1. Performance: In large apps with hundreds of inputs, skipping unnecessary checks saves CPU cycles and battery life on mobile devices.
  2. Predictability: It forces you to use Immutability (like in Redux or modern .NET patterns), which makes debugging easier.
  3. Modern Standards: When using Angular Signals, the framework handles these updates even more efficiently, but understanding OnPush remains a core skill for any senior Angular developer.


Share this lesson: