Извините, если на этот вопрос уже был дан ответ, но я не смог найти соответствия для нашего конкретного сценария, так что здесь!
Мы провели обсуждение в нашей команде разработчиков относительно вызовов функций в угловых шаблонах. Теперь, как общее практическое правило, мы согласны, что вы не должны делать это. Тем не менее, мы попытались обсудить, когда это может быть хорошо. Позвольте мне дать вам сценарий.
Допустим, у нас есть блок шаблона, который обернут в ngIf, который проверяет множество параметров, как здесь:
<ng-template *ngIf="user && user.name && isAuthorized">
...
</ng-template>
Будет ли существенная разница в производительности по сравнению с чем-то вроде этого:
Шаблон:
<ng-template *ngIf="userCheck()">
...
</ng-template>
Машинопись:
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized;
}
Итак, чтобы подвести итог вопроса, будет ли последний вариант иметь какие-либо существенные затраты производительности?
Мы предпочли бы использовать второй подход, в ситуациях, когда нам нужно проверить более двух условий, но многие статьи онлайн говорят, что вызовы функций ВСЕГДА плохи в шаблонах, но действительно ли это проблема в этом случае?
источник
Ответы:
Я также старался максимально избегать вызовов функций в шаблонах, но ваш вопрос вдохновил меня на быстрое исследование:
Я добавил еще один случай с
userCheck()
результатами кешированияПодготовил демо здесь: https://stackblitz.com/edit/angular-9qgsm9
Удивительно, но похоже, что нет никакой разницы между
А также
А также
Это похоже на то, что это действительно для простой проверки свойств, но определенно будет разница, если речь идет о каких-либо
async
действиях, например, получателях, ожидающих некоторый API.источник
Это довольно самоуверенный ответ.
Использование таких функций вполне приемлемо. Это сделает шаблоны намного понятнее и не вызовет значительных накладных расходов. Как сказал ранее JB, он послужит гораздо лучшей базой для модульного тестирования.
Я также думаю, что любое выражение в вашем шаблоне будет оцениваться как функция механизмом обнаружения изменений, поэтому не имеет значения, есть ли оно в вашем шаблоне или в логике компонента.
Просто сведите логику внутри функции к минимуму. Однако, если вы настороженно относитесь к влиянию на производительность, которое может иметь такая функция, я настоятельно рекомендую вам применить
ChangeDetectionStrategy
ееOnPush
, что в любом случае считается наилучшей практикой. При этом функция не будет вызываться каждый цикл, только когдаInput
изменения, какое-то событие происходит внутри шаблона и т. Д.(используя и т. д., потому что я больше не знаю другую причину) .
Лично, опять же, я думаю, что еще лучше использовать шаблон Observables, тогда вы можете использовать
async
конвейер, и только когда новое значение будет получено, шаблон будет переоценен:Затем вы можете просто использовать в шаблоне, как это:
Еще одним вариантом будет использование
ngOnChanges
, если все зависимые переменные для компонента являются входами, и у вас есть много логики для вычисления определенной переменной шаблона (что не так, как вы показали):Что вы можете использовать в своем шаблоне, как это:
источник
Observable
поток, что сделает его идеальным кандидатом для второго варианта, который я показал. В любом случае, рад, что я мог дать вам некоторые идеиНе рекомендуется по многим причинам основной:
Чтобы определить, нужно ли повторно визуализировать userCheck (), Angular необходимо выполнить выражение userCheck (), чтобы проверить, изменилось ли его возвращаемое значение.
Поскольку Angular не может предсказать, изменилось ли возвращаемое значение userCheck (), он должен выполнять функцию каждый раз, когда запускается обнаружение изменений.
Таким образом, если обнаружение изменений выполняется 300 раз, функция вызывается 300 раз, даже если ее возвращаемое значение никогда не изменяется.
Расширенное объяснение и другие проблемы https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496
Проблема возникает, когда ваш компонент большой и посещает много событий изменений, если ваш компонент будет маленьким и просто посетит несколько событий, не должно быть проблемой.
Пример с наблюдаемыми
Затем вы можете использовать это в наблюдаемом асинхронном канале в вашем коде.
источник
Я думаю, что JavaScript был создан с целью, чтобы разработчик не заметил разницу между выражением и вызовом функции в отношении производительности.
В C ++ есть ключевое слово
inline
для обозначения функции. Например:Это было сделано для того, чтобы исключить вызов функции. В результате компилятор заменяет все вызовы
userCheck
на тело функции. Причина для инновацийinline
? Повышение производительности.Поэтому я думаю, что время выполнения вызова функции с одним выражением, вероятно, медленнее, чем выполнение только выражения. Но я также думаю, что вы не заметите разницы в производительности, если у вас есть только одно выражение в функции.
источник