Как улучшить производительность в Angular с помощью Memoize Pipe

Angular — это мощный инструмент для создания сложных веб-приложений. Но, как и в любом другом фреймворке, возникают свои сложности. Одна из таких проблем — это частые перезапуски тяжелых функций в шаблонах, что сильно бьет по производительности. Если приложение начинает тормозить, значит пора задуматься об оптимизации. И здесь на помощь приходит Memoize Pipe, способный спасти ваш интерфейс от лишних вычислений.

bca10467e7556ced6cf12487deb87139.jpg

Проблема: Повторные вызовы функций

Каждый раз, когда Angular проверяет изменения, он повторно вызывает функции в шаблоне, игнорируя предыдущий результат. Это может стать проблемой, когда дело касается сложных вычислений или обращений к API.

@Component({
  ...
  template: `
    {{ heavyComputation(person, index) }}
  `,
})
export class AppComponent {
  heavyComputation(name: string, index: number) {
    // Очень тяжелые вычисления
  }
}

Решение: Memoize Pipe для повышения производительности

Создавать отдельный pipe для каждой функции не всегда удобно, особенно если функция больше нигде не используется. Хочется универсального и гибкого решения, и именно это предлагает Memoize Pipe. Он позволяет запоминать результаты функций, избегая их повторного вызова, если входные данные остались неизменными. Это снижает нагрузку на приложение и улучшает производительность.

Пример использования:

Изначально у вас есть шаблон с вызовом функции:

@Component({
  ...
  template: `
    {{ heavyComputation(person, index) }}
  `,
})
export class AppComponent {
  heavyComputation(name: string, index: number) {
    // Очень тяжелые вычисления
  }
}

Теперь добавим мемоизацию:

Установим библиотеку:

npm i @ngx-rock/memoize-pipe

Затем импортируем FnPipe и используем его в шаблоне:

@Component({
  ...
  template: `
    {{ heavyComputation | fn : person : index }}
  `,
})
export class AppComponent {
  heavyComputation(name: string, index: number) {
    // Очень тяжелые вычисления
  }
}

Теперь Angular не будет каждый раз пересчитывать функцию, если значения её аргументов не изменились (примитивы и ссылки для массивов и объектов).

Сохранение контекста this

Если ваша функция зависит от переменных компонента, то нужно сохранить контекст. Это можно сделать с помощью стрелочной функции:

@Component(...)
export class AppComponent {     
  heavyComputation = (name: string, index: number) => {
    // Очень тяжелые вычисления
  }
}

Поддержка standalone модулей

Последние версии Memoize Pipe реализованы в виде standalone модулей.

import { FnPipe } from "@ngx-rock/memoize-pipe";

@Component({
  ...
  standalone: true,
  imports: [ FnPipe, ... ]
  ...
})
export class AppComponent { ... }

Заключение: Простая оптимизация — ощутимый результат

Когда речь идет о производительности, порой самые простые решения оказываются наиболее эффективными. Memoize Pipe — это как раз такое решение: оно помогает уменьшить количество вызовов функций, ускоряя работу приложения. Помимо этого упрощает процесс написания кода.

@ngx-rock/memoize-pipe

© Habrahabr.ru