5

The a simple ternary operator can be used like this within html:

<div> {{ showStringOneFlag ? 'Display String 1' : 'Display String 2' }} </div>

This may be more convenient than setting a string variable 20 times in javascript.

My question is if the ternary operator is too expensive to be executed each digest cycle? Should this function be avoided or used sparingly? Is its footprint minimal on the digest cycle and there is no need to worry about it? Everywhere I look for an answer I see that it is comparable to an if/else statement in terms of speed, but in html there isn't really an equivalent to an if/else statement.

Ling Vu
  • 4,740
  • 5
  • 24
  • 45
rhavelka
  • 2,283
  • 3
  • 22
  • 36
  • 2
    What you're showing has absolutely zero meaning in HTML. It just represents the literal text "{{ showStringOneFlag ? 'Display String 1' : 'Display String 2' }}" inside a `div`. – deceze Dec 03 '19 at 15:55
  • @deceze I asked a similar question a few days ago and included that I was using angular, but everyone starting hopping on "why don't you use ngIf?" or "why don't you offload it to the component?" and they kept dodging my question with alternate solutions that I knew about, but didn't answer the question I was asking. – rhavelka Dec 03 '19 at 17:16
  • 1
    With the additional context of [tag:angular] this now makes some sense, before it didn’t... – deceze Dec 03 '19 at 17:58
  • really, I think it is not expensive. in fact, for me, is the Angular way to make the things if the "variable" change along the life of Angular. Of course, if the "variable" not change else at first of the app (or in the ngOnInit) and there're so many elements that depends of the variable, you can consider declare a variable or make a map if you has an array and show the variable declared – Eliseo Jan 10 '20 at 08:10
  • 1
    Do you just want to measure the performance of the ternary operator by itself or compare it to some other method (like a pipe for example)? – igg Jan 10 '20 at 11:16
  • 1
    @IraklisGkougkousis exactly. I am wondering if it's treated like an `*ngIf` or a `pipe` where it only recalculates on input changes, or if it is more like adding a function that calculates on every digest cycle. – rhavelka Jan 10 '20 at 15:21
  • @rhavelka can't you just use function call which must return a string? And can you clarify what exactly you went to do – Navruzbek Noraliev Jan 11 '20 at 09:44
  • 1
    @rhavelka by digest cycle, do you mean lifecycle? Regardless, the expression interpolated between the curly bracers will be reevaluated at each ngOnChanges cycle. – Dane Brouwer Jan 13 '20 at 14:18
  • @NavruzbekNoraliev read the line "This may be more convenient than setting a string variable 20 times in javascript." – rhavelka Jan 13 '20 at 17:10
  • @DaneBrouwer I usually call it the digest cycle, but it might be the life cycle. It's when the html recalculates all your values on events, such as a mouse move. So you're saying that the full ternary will be recalculated and it is not treated like a pipe? – rhavelka Jan 13 '20 at 17:15
  • @rhavelka "Angular will continuously re-evaluate interpolated values on each and every turn of the digest cycle, and re-render the displayed string, even if it has not changed." - https://www.codelord.net/2017/03/23/the-performance-difference-between-ng-bind-and-%7B%7B%7D%7D/ – Dane Brouwer Jan 14 '20 at 07:28

4 Answers4

12

1) Is the ternary operator too expensive to be executed each digest cycle?

The ternary operator itself should not be to expensive to be executed at each digest cycle. A ternary operator should evaluate in the region of microseconds. With that said, if you call a function that evaluates to a truthy/falsy or if your ternary operator itself calls a function, then it could take upwards of milliseconds depending on how expensive your function is.

2) Should this function be avoided or used sparingly?

If they are clean ternary operators, i.e. make explicit comparisons without function calls, then you should be able to use as many as you like, there should be no significant impact.

3) Everywhere I look for an answer I see that it is comparable to an if/else statement in terms of speed, but in html there isn't really an equivalent to an if/else statement.

Angular Interpolation is Javascript, not HTML.

So if you want to look at a comparison, you can look at the performance difference between a ternary operator and an if-statement in pure JS. However, I'm sure the performance difference should be negligble.

Further Reading to help understand how Angular interprets and processes HTML.

Dane Brouwer
  • 2,827
  • 1
  • 22
  • 30
3

Short answer is it depends on what you are rendering conditionally, and if it makes sense to use a ternary.

For simple conditional rendering, sure, a ternary is fine and will not affect performance in a noticeable manner.

However, if you are rendering giant chunks of code conditionally, or performing several/complex computations at several points in your code to determine what is rendered, it may be wiser to perform this step outside of the HTML.

For more information see this SO link

RGordon
  • 39
  • 7
2

HTML is a declarative markup language and does not support control structures like if statements. Most likely you're referring to some template engine which - as of now - is unknown and cannot be reasoned about.

ldz
  • 2,217
  • 16
  • 21
0

If you want to use this widely in your application I think you could as long as you don't use it along side Angular's default change detection strategy. By default DOM events, xhr, and timers will trigger change detection which will cause Angular to re-evaluate that expression, if you have never dealt with angular's default change detection policy before let me assure you it runs A LOT more than you might think. If you have ever put a console log in a component only to see it logged hundreds of times in your dev tools, that is likely the default policy mixed with a function in your template.

So what other policy is there? OnPush

In broad strokes, you can use OnPush detection if your component ONLY gets it's data from @Input (as it would in a container/presentation component model). If you do this, instead of Angular running change detection on DOM events, xhr, and timers it will ONLY run change detection when the @Input changes which is obviously much more efficient.

TL;DR
if you want to use that expression frequently you should consider using OnPush change detection, which will prevent it from needlessly re-evaluating the expression.

intros to change detection:
https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
https://medium.com/@bencabanes/angular-change-detection-strategy-an-introduction-819aaa7204e7

Colton Williams
  • 294
  • 1
  • 5
  • 24