OnPush-Komponenten rendern immer dann neu, wenn ein `@Input()` eine neue Objektreferenz erhält — auch wenn dieses Objekt strukturell mit dem vorherigen identisch ist. Das ist eine häufige Quelle verschwendeter Change-Detection-Zyklen in Angular-Bäumen, in denen Eltern-Komponenten Filter- oder Konfigurationsobjekte bei jedem Render neu aufbauen. Die Kapselung des Setters in eine strukturelle Gleichheitsprüfung durchbricht diese Kopplung an die Referenzidentität: Der Input-Setter läuft bei jeder Referenzänderung, aber die teure Neuberechnung erfolgt nur, wenn sich die tatsächlichen Feldwerte unterscheiden. Das unterscheidet sich von `distinctUntilChanged` auf einem Observable-Stream, da hier ein einfaches `@Input()`-Binding ohne Operator-Pipeline abgesichert wird.
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';interface Filters {status: readonly string[];minPrice: number;}function sameFilters(a: Filters, b: Filters): boolean {return (a.minPrice === b.minPrice &&a.status.length === b.status.length &&a.status.every((s, i) => s === b.status[i]));}@Component({selector: 'app-catalog',standalone: true,changeDetection: ChangeDetectionStrategy.OnPush,template: `<app-list [items]="visibleItems" />`,})export class CatalogComponent {private lastFilters: Filters | null = null;visibleItems: unknown[] = [];@Input() set filters(next: Filters) {if (this.lastFilters && sameFilters(this.lastFilters, next)) {return;}this.lastFilters = next;this.visibleItems = this.recompute(next);}private recompute(f: Filters): unknown[] {return [];}}