Skip to main content
Практика завдань

Як працює виявлення змін в Angular?

Що таке виявлення змін?

Виявлення змін — це механізм Angular, який моніторить зміни даних і оновлює шаблон (DOM), якщо це необхідно.

Коли щось змінюється в додатку — Angular ініціює процес виявлення змін і порівнює значення компонентів з тим, що вже відрендерено, щоб визначити, чи потрібно оновлювати DOM.


Як це працює?

  1. Angular починає перевірку з кореневого компонент.
  2. Пересувається вниз по дереву компонентів.
  3. Перевіряє кожне зв'язування ({{ value }}, [property], (event)) на зміни.
  4. Якщо значення змінилося — DOM оновлюється.

Що ініціює виявлення змін?

Angular використовує бібліотеку zone.js для автоматичного "захоплення" подій, що викликають зміни:

Джерело змінПриклад
Події DOMclick, input, change тощо.
ТаймериsetTimeout, setInterval
HTTP запитиHttpClient
Promise та async/awaitfetch().then(...), await
Внутрішні зміниthis.value = ...

Приклад: Автоматичне оновлення DOM

typescript
@Component({ selector: 'app-example', template: `<p>{{ counter }}</p> <button (click)="increment()">+</button>` }) export class ExampleComponent { counter = 0; increment() { this.counter++; } }

Angular автоматично відстежує зміну counter після натискання кнопки і оновлює DOM.

Стратегії виявлення змін

Angular підтримує дві стратегії виявлення змін:

СтратегіяОпис
DefaultAngular перевіряє всі компоненти при будь-якій зміні
OnPushAngular перевіряє компонент лише тоді, коли змінюються параметри Input або відбуваються події

Використання OnPush:

typescript
@Component({ selector: 'app-optimized', changeDetection: ChangeDetectionStrategy.OnPush, template: `<p>{{ user.name }}</p>` }) export class OptimizedComponent { @Input() user!: { name: string }; }

Це зменшує кількість перевірок, покращуючи продуктивність, особливо в великих додатках.

Як Angular порівнює значення?

Angular використовує порівняння за посиланням (поверхневе порівняння):

typescript
this.user.name = "John"; // не ініціює OnPush! this.user = { name: "John" }; // ініціює, бо нове посилання

Щоб оновити компонент зі стратегією OnPush — потрібно створити новий об'єкт.

Як оптимізувати виявлення змін?

  • Використовуйте ChangeDetectionStrategy.OnPush скрізь, де це можливо.
  • Уникайте частих мутацій об'єктів/масивів (використовуйте незмінність).
  • Використовуйте trackBy в *ngFor, щоб уникнути непотрібних повторних рендерингів.
  • Працюйте з ChangeDetectorRef та NgZone для ручного управління:
typescript
constructor(private cdr: ChangeDetectorRef) {} update() { this.value = newValue; this.cdr.detectChanges(); // вручну ініціювати перевірку }

Важливо: OnPush не означає, що компонент ніколи не оновлюватиметься. Він все ще реагує на зміни вхідних даних і події (клік, введення).

Важливо: Використання ChangeDetectorRef.detectChanges() вважається поганою практикою, оскільки воно порушує автоматичний механізм виявлення змін, ініціює непотрібний рендеринг, який може не бути необхідним, і створює непередбачувану поведінку. Для оптимізації зазвичай використовують markForCheck() або detach/reattach (ніколи не бачив останнього на живому проекті). Angular має механізми реактивного програмування: сигнали, обсервації та вхідні дані. Краще використовувати їх для коректного рендерингу.

Читати більше тут.

Зміст

Що таке виявлення змін?Як це працює?Що ініціює виявлення змін?Приклад: Автоматичне оновлення DOMСтратегії виявлення змінЯк Angular порівнює значення?Як оптимізувати виявлення змін?

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань