В этой статье я хочу рассказать о новой функции, представленной в последней версии Angular (v9) - ngZoneEventCoalescing. Во-первых, нам нужно понять проблему, которую он призван решить. Допустим, у нас есть шаблон следующего компонента:

Когда мы нажимаем на элемент кнопки, он сначала запускает обработчики на нем, затем на его родительском элементе, а затем продолжает движение вверх по дереву DOM. Это так называемое всплытие событий. (🦊)

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

Возвращаясь к нашему фрагменту кода, когда мы нажимаем кнопку, мы также вызываем обработчик родительского элемента, вызывая запуск двух циклов обнаружения изменений. Давайте посмотрим на это в действии:

Как мы видим, Angular вызывает метод tick дважды, по одному для каждого обработчика событий.

Начиная с Angular v9, у нас есть возможность указать Angular объединять эти события. Мы делаем это, устанавливая для нового свойства ngZoneEventCoalescing значение true в методе bootstrapModule:

Теперь, если мы запустим тот же процесс, мы увидим, что Angular выполняет только один цикл обнаружения изменений:

Если мы посмотрим на исходный код, мы увидим, что он работает, используя простую проверку того, хотим ли мы объединить события:

В этом случае Angular откладывает цикл обнаружения изменений с помощью requestAnimationFrame.

🚀 На случай, если вы это пропустили

Вот несколько моих проектов с открытым исходным кодом:

  • Акита: государственное управление, специально разработанное для JS-приложений
  • Spectator: мощный инструмент для упрощения ваших угловых тестов
  • Transloco: библиотека интернационализации Angular
  • Forms Manger: основа правильного управления формами в Angular
  • Кешью: гибкая и простая библиотека, которая кэширует HTTP-запросы.

Подпишитесь на меня в Medium или Twitter, чтобы узнать больше об Angular, Akita и JS!