Overhead for Components not displayed or visible with Null bindings

Hello,

In my work of optimizing the performance of our perspective views, I have learned that components that are bound to non- tags that don't exist can create some overhead in a View. To keep up with efficiency for my coding updates, I am trying to get a better understanding of how these bindings are evaluated.

Are a component's bindings to props (ex. the text prop for a label) evaluated only when the tag is visible/displayed? If not (meaning evaluated all the time), should I put isNull checks in all bindings whose tags may or may not exist (ex. dynamic views)?

Thanks for your help!

If a component exists, full stop, there is overhead on the gateway.
If a component is invisible (visible=false), there is overhead on the frontend session (layout effort in the DOM).
If a component is not displayed (display=false), there's still overhead on the gateway and the frontend session to manage the component, but there's no layout effort.

If a component has bindings, scripts, etc, there's additional overhead on the gateway.
If a component has changing property values, there's additional overhead on the gateway, the frontend session, and the websocket they use to communicate.

1 Like

Thanks for the information on the overhead. I just need a little more clarification.

So for example, if a label component has its text value bound to a tag that does not exist, is it the same degree of overhead regardless of whether that component is visible/invisible/not displayed?

A more direct example would be:

A label component has a binding on its meta.visible prop that hides the component if a tag does not exist (something like !isNull(tag("[default]String")) ). The props.text value is bound to that tag. If the tag does not exist, the component is hidden, but does the props.text binding still execute in the background (carrying with it the overhead for evaluating a null value)?

Thanks!

Yes. A binding has no awareness of where it's used, such as whether the component it's attached to is visible or not; it will always evaluate, and there is (generally) no "short-circuiting", where an earlier conditional will prevent later evaluations from occurring.

1 Like

So a single popup that 'mutates' to serve multiple purposes is less performant than multiple popups, correct?

Perhaps there is some balance where the performance loss is less painful then the development cost.

Does that mean that the following expression would have null evaluation overhead on both parts of the "if" statement if the tag doesn't exist (instead of working like a Null Conditional that shorts code in other languages)?

if(!isNull(tag("[default]Status")),tag("[default]Status"),false)

Nevermind, I think I got this figured out. In that code snipper from that last response, the true section would not execute if the tag does not exist, so there would not be that null verification there.

Thanks, Paul, for getting this answered for me, that helps a lot!

Well, I stand corrected having looked at the code. In the particular case of the if expression, at least, the true or false expressions are evaluated or not based on the input condition.

So, the if condition will obviously always be evaluated, but there is a sort of short-circuiting in place.

That said, your example there can (and should) avoid the use of the tag() function, which is a huge performance trap. If you don't need a dynamic tag lookup inside your expression function, always prefer the curly-brace {path/to/tag} syntax. It's significantly faster.

5 Likes

Y'all might find the new timeMe() expression function helpful when examining this sort of question, and more complex ones....

2 Likes

I suggest replacing this with coalesce({[default]status}, false).
If the paths are dynamic, use a custom property to first fetch the tag value with an indirect tag binding, then use an expression binding with coalesce({custom_property}, false),
Or use an indirect tag binding with an expression transform coalesce(value, false).
It's also doable with a single expression binding by doing string concatenation to build the path, but I'm not a huge fan of this solution, unless the path is really simple.

1 Like

Question just went through my mind...

Let's say I'm building an object depending on some property. That object always has the same structure and keys, only the values change.
At which point, if ever, does it become more efficient to generate the whole dict through a script transform, rather than generating each key/value pair with a simple expression binding ?

Pssst! Try my asMap() expression function... In the above linked Simulation Aids V2.

I wish. Not allowed to use third party modules.

1 Like

Oy! Situations like yours is one of the reasons I give away Simulation Aids--to break down certain counterproductive administrative barriers. This latest module, if used to replace common scripted transforms with expressions, could improve Perspective performance 2x or more, enabling many more clients to be supported on given hardware. Are your bosses willing to spend gobs more on infrastructure over this?

The argument is that you don't control third party ressources and you can't know how they'll behave with ignition updates.
Now, I'd totally trust your modules to play nice, but I'm not the decision maker here.
Though they're quite open to try things if we bring reasonable arguments... Maybe I could try convincing them.

1 Like

Indeed. But you have to trust somebody.

FWIW, my business is older than Inductive Automation (by about a month). Automation Professionals, with me as one of the founding owners, opened its doors on January 2, 2003.

Keep in mind that by using Ignition, you are depending on an upstart company that all the major players in the automation business would be delighted to crush into dust.

Eh, we're just a few months younger I believe !
Though I only joined them a few months ago.
edit: actually we turn 21 in a couple weeks ! 15 years with IA...

I'll see if I can make a case for simulation aids, I do believe it would be a great addition.