Async pipe не чистий: розвінчуємо міф

Якщо ви працювали з Angular, то напевно знайомі з async pipe — зручним способом підписки на Observable прямо в шаблоні. Але в певний момент ви могли почути фразу: “Async pipe не чистий”. Що це означає і чи справді є підстави для занепокоєння? Розбираємось по-людськи.

Що таке pure та impure pipes в Angular

У Angular pipes поділяються на “чисті” (pure) та “нечисті” (impure). Чиста pipe виконується лише тоді, коли змінюється вхідне значення. Нечиста — щоразу, коли Angular запускає зміну детекції (а це часто).

У декларації pipe:

@Pipe({
  name: 'customPipe',
  pure: false
})

Якщо pure: false, Angular буде викликати цю pipe набагато частіше.

Async pipe і її поведінка

Async pipe виглядає зручним:

<p>{{ user$ | async }}</p>

Вона автоматично:

  • підписується на Observable;
  • повертає останнє значення;
  • відписується при знищенні компонента.

Однак за капотом async pipe є нечистою. Вона викликається кожного разу, коли Angular виконує change detection, щоб перевірити, чи не змінилось значення Observable.

Чи це погано?

Не зовсім. Angular оптимізований для роботи з таким шаблоном, і більшість змін не є критичними. Але якщо:

  • ваш компонент часто оновлюється (через setInterval, події чи сторонні тригери);
  • є велика кількість async pipe в одному шаблоні;
  • ваші Observables складні, потребують перерахунку;

…ви можете помітити погіршення продуктивності.

Альтернативи та підходи

  1. Передплата в компоненті:
ngOnInit() {
  this.user$?.subscribe(user => this.user = user);
}

Але потрібно не забути unsubscribe.

  1. Push ChangeDetectionStrategy + сигналізація: Використання OnPush та Subject’ів/Signal’ів для більш контрольованих оновлень.
  2. Memoization та кастомні pipes: Якщо ви точно знаєте, що значення не змінюється щодня — кешуйте.

Висновок

Async pipe — зручний, безпечний і загалом ефективний інструмент. Але варто пам’ятати, що він не є “чистим” у сенсі Angular. Це означає, що для критично навантажених компонентів чи у високочастотних потоках даних його краще замінювати або контролювати.

Знання про “нечистоту” async pipe не має лякати — воно допоможе писати більш ефективний код, коли це справді потрібно.