InterviewHubPRO
Section Overview
Q204

Question 204 of 283

Part 8: Internationalization (i18n), Testing & DOM Directives (177 - 212)

72%
Angular & Signals (283 Qs)•Part 8: Internationalization (i18n), Testing & DOM Directives (177 - 212)

What is the purpose of ngFor trackBy?

The trackBy function in *ngFor (and mandatory track in @for) is a critical performance optimization mechanism for DOM reconciliation when rendering collections.

1. The Problem: Default Reference Checking

By default, without identity tracking, when an array changes (e.g., when refreshed from an API), Angular compares object references (===). Even if the items contain identical data, new object references cause Angular to:

  1. Tear down all existing DOM elements in the list.
  2. Re-create and re-insert new DOM elements from scratch.
  3. Cause screen flickering, loss of scroll position, and loss of focused input states.

2. Classic Built-in Syntax: *ngFor with trackBy

In classic *ngFor, you write a method in your component and pass it via trackBy: trackById:

typescript
// Component TypeScript logic
trackById(index: number, todo: Todo): number {
  return todo.id; // Returns unique identity
}
html
<!-- Component Template -->
<div *ngFor="let todo of todos; trackBy: trackById">
  ({{ todo.id }}) {{ todo.name }}
</div>

3. Modern Built-in Control Flow: Mandatory track in @for (Angular 17+)

In Angular 17+, track is strictly mandatory in @for. You can write the identity expression directly in the template without creating helper functions in the component:

html
<!-- Direct property tracking (Zero component boilerplate) -->
@for (todo of todos; track todo.id) {
  <div>({{ todo.id }}) {{ todo.name }}</div>
}

<!-- Fallback for primitive arrays without unique IDs -->
@for (item of tags; track $index) {
  <span class="tag">{{ item }}</span>
}

4. Performance Comparison: With vs Without Tracking

text
Without track / trackBy:
[Item A (0x01), Item B (0x02)] -> API Reload -> [Item A (0x03), Item B (0x04)]
Angular destroys 2 DOM nodes and creates 2 new DOM nodes!

With track / trackBy (track item.id):
[Item A (id=1), Item B (id=2)] -> API Reload -> [Item A (id=1), Item B (id=2)]
Angular detects id=1 and id=2 exist! Re-uses identical DOM nodes, only updating changed text!