По умолчанию Angular использует ChangeDetectionStrategy.Default стратегию обнаружения изменений. ChangeDetectionStrategy.Default работает таким образом, что каждый раз, когда что-то меняется в нашем приложении, в результате различных пользовательских событий, таймеров, XHR, промисов и т.д., обнаружение изменений будет запускаться по всем компонентам. Можем увидеть это на простом примере. Создадим в компоненте геттер и используем его в нашем шаблоне. Например: Каждый раз, когда мы нажимаем на кнопку, Angular будет запускать цикл обнаружения изменений и в консоли мы увидим два лога “Checking the view” (или один в продакшн моде). Этот цикл называется грязной проверкой (dirty checking). Суть проверки заключается в том, что Angular сравнивает новые значения со старыми и обновляет представление если они не равны. Теперь представьте большое приложение с огромным количеством компонентов и множеством условий. Если мы позволим Angular, каждый раз, когда запускается цикл обнаружения изменений, проверять каждое из этих условий, это негативно скажется на производительности. Не смотря на то, что Angular неплохо оптимизирован, в процессе роста приложения, ему придется работать все больше и больше. Что, если мы поможем Angular и дадим ему более явные индикаторы, когда нужно проверять наши компоненты? Мы можем изменить ChangeDetectionStrategy.Default на ChangeDetectionStrategy.OnPush. Это означает, что компонент теперь зависит только от @inputs() параметров, и будет проверятся только при таких условиях: Установив OnPush стратегию, мы как бы подписываем договор с Angular, который обязывает нас работать с иммутабельными объектами (или наблюдаемыми (observables), как мы увидим дальше). Преимущество работы с иммутабельными данными в контексте обнаружения изменений в том, что Angular выполняет простую проверку по ссылке, чтобы решить, следует ли проверять представление. Это намного быстрее чем глубокое сравнение объектов. Попробуем мутировать объект и посмотрим на результат: После клика на кнопку, мы не увидим никаких логов в консоли. Angular просто сравнил старое и новое значения по ссылке, которая осталась прежней. Как мы знаем, числа, булевые, строки, null и undefined это примитивные типы. Все примитивные типы передаются по значению. Объекты, массивы, и функции передаются по ссылке. Чтобы запустить механизм обнаружения изменений, мы должны изменить саму ссылку на объект. После этого изменения, мы увидим, что представление было проверено и значение изменилось, как мы и ожидали. Компонент может иметь внутреннее состояние, которое обновляется когда возникает событие от самого компонента или его потомков. Например click: Когда мы жмем на кнопку, Angular запускает цикл обнаружения изменений и представление обновляется, как и ожидалось. Возможно, вы думаете, что все асинхронные операции также должны быть триггером запуска механизма обнаружения изменений, как мы и говорили вначале, но нет. Правило применяется только к событиям DOM, поэтому следующий код не станет триггером механизма. Обратите внимание, что свойство count изменилось, поэтому при следующем цикле обнаружения изменений, когда мы нажмем на кнопку, значение будет 6 (5 + 1). Angular предоставляет нам три метода для самостоятельного запуска механизма обнаружения изменений и мы можем вызывать их в нужных нам местах. Первый detectChanges() говорит Angular запустить обнаружение изменений в компоненте и его потомках. Второй ApplicationRef.tick() говорит Angular запустить обнаружение изменений во всем приложении. И третий markForCheck(), который не триггерит запуск обнаружения изменений. Вместо этого он помечает компонент и всех его родителей, что они должны быть проверены в текущем или следующем цикле обнаружения изменений. Стоит обратить внимание, что ручной запуск механизма обнаружения изменений не является плохой практикой. Использование данных методов вполне по дизайну и допустимо (конечно в необходимых случаях). Async пайп подписывается на наблюдаемый объект или промис и возвращает последнее отданное им значение. Давайте посмотрим на простой пример компонента с OnPush и наблюдаемым (observable) input параметром. После нажатия на кнопку, мы не увидим обновленное представление. Это связано с тем, что ни одно из описанных нами выше условий не произошло. Поэтому Angular не будет проверять компонент в текущем цикле обнаружения изменений. Теперь давайте используем async пайп. Как видим, теперь представление обновляется. Когда приходит новое значение, async пайп отмечает компонент как необходимый к проверке. Можем видеть это в исходниках: Angular вызывает markForCheck(), поэтому представление обновляется даже когда ссылки не изменились. Если компонент зависит только от входящих параметров, и они наблюдаемы, то этот компонент может изменится только если один из параметров генерирует событие. Совет: Антипаттерном считается отдавать во внешний мир subject, лучше всегда отдавать наблюдаемый объект, используя asObservable() метод. Рассмотрим следующие компоненты: Вероятно, вы думаете, что Angular через 3 секунды обновит представление app-tab компонента новым значением. Мы же видели что если обновить ссылку в OnPush компоненте, это должно запустить механизм обнаружения изменений, не так ли? К сожалению, в данном примере это не работает. Angular не знает, что мы обновили свойство в app-tab компоненте. Только определив input параметр в шаблоне, Angular поймет, что это свойство нужно проверить в следующем цикле обнаружения изменений. Например: Поскольку мы явно определили input параметр в шаблоне, Angular создаст updateRenderer() функцию, которая отслеживает изменения значений параметров в каждом цикле обнаружения изменений. 
AppComponent.ngfactory.ts Простым решением в этом случае будет создание сеттера и вызов markForCheck(). После того как мы поняли (надеюсь) всю мощь OnPush, мы можем создавать более оптимизированные приложения. Чем больше компонентов с OnPush стратегией мы имеем, тем меньше проверок будет выполнять сам Angular. Рассмотрим реальный пример: Допустим у нас есть todos компонент, в котором определено свойство todos с декоратором Input. Недостатком данного примера является то, что при нажатии кнопки Add, Angular будет проверять на изменения каждое todo. И при первом нажатии мы увидим в консоли три лога. В примере выше делается только одна проверка, но представьте себе компонент из реального большого приложения, с несколькими условиями и привязками данных (ngIf, ngClass, выражения, и т.д.). Это может существенно влиять на производительность. Мы запускаем обнаружение изменений без причин Эффективным решением будет создать компонент с OnPush стратегией для конкретного todo. Например: Теперь при клике на кнопку, мы увидим только один лог. Поскольку ни один input параметр других todo не изменился, их представление не будет проверятся. Также логическое разделение компонентов сделает ваш код более читабельным и переиспользуемым. Web Developer