Template settings - removing the tag() expressions

Hello

Long story short, our windows are slow to the point of unresponsiveness. Based on previous posts, we suspect one culprit might be the use of the tag() expression in our templates.

I think I've worked a way around it by using a lot of internal properties to replace the tag() expressions, but I want to be sure I won't be making things worse before we go through and redo everything :cry:

The issue is that we created templates to be flexible enough to handle UDTs that may or may not contain all the items we want to display. So the template has multiple custom parameters for the tagpath for various inputs, and if the tagpath is blank, the template ignores by using the isgood(tag({tagpath})) logic. The only way I managed to get around that when converting to internal properties is the set the "Overlay Opt-out" checkbox on the internal properties that have indirect tags. Since sometimes the parameter is blank so the indirect tag property is in error status with no way to check isgood() since we can't use the expression within an indirect tag assignment.

Will having these errors existing but hidden, just cause new problems?

Also is there a better way than creating like 40 internal properties separately on all our templates? Could we abstract those properties to a shared dataset or something? But again, there will be a lot of properties that don't exist or don't apply to every template so I'm worried we are just moving the problem.

I was so disappointed to learn about the tag() function issues. It is super frustrating that IA provides something that makes complicated tasks easier and even teaches you how to use it without warning about the side effects. We were so proud of our smart templates that could accept all manner of tags.

You're going about it correctly. The tag() expression is fine to use in expression tags but has the severe performance impact you're seeing when used in expression bindings. It gets even worse once you get a lot of templates on the screen to the point where it's almost unusable. I've had to go behind other integrators myself to redo their templates because the end user was having performance problems. One was so bad that they were unable to launch the client from a remote location and only clients on the local network would work.

If you haven't already, consider installing the Tag Expression Blocker resource from the Ignition Exchange. It removes the tag() option from the advanced functions popup and will block future developers from adding anymore tag expressions to the project while directing them toward proper indirect bindings.


Tag Expression Blocker DEMO

Ok, so it's normal for template to have a huge number of internal properties? Is it still safe to use the isgood() function on the internal property to check if it exists? If that is ok then I wouldn't have to have a separate property that is checking the .Enabled bit of each tag that I want to read, I could just do an isgood() on the property that is indirecting to the actual value.

I typically make individual templates for the different types, but I'd think you could do it this way if you want. I don't know how much overhead it takes to have bindings to tags that don't exist. (Do the tags exist and just aren't enabled, or do they simply not exist?) Client will still be trying to read them and at scale, this would create a lot of excessive bindings that aren't necessary.

You might check out the Ignition Extensions module which has an isAvailable() expression that checks that a tag path is both found and enabled.

I would say this is fairly normal, though there could be an argument that you might want to refactor the template into more less generic templates.

For instance, while it is possible to have a template that handles both a motor with a starter and a motor with VFD, I would create two separte templates. ( A bit of a contrived example, but not invalid.)

From a performance perspective, you really don't want to be wasting a lot of processing on properties that are not going to be used. In some situations it probably isn't going to be that impactiful, but in others it might be very impactful. There is a balancing act there between performance impact and development/maintenance time/work. Personally, I try to minimize the number of properties which are being processed needlessly.

Yes, we've had this "balancing act" conversation so much. We have a lot of different equipment. So yes, we have a separate UDT and template for fixed pumps versus VFDs, but some have faults, some don't, some have two commands, some have one command, some have "available" tags, some don't, some have leak detection, some don't. So if we have to make a new UDT and template for every combination of those, I'm honestly not sure a template would even be useful, we might not even have more than 2 pumps that are exactly the same. We thought we had landed on a good solution - where the tag() expression let us handle all these different cases. :frowning:

I haven't read your whole post yet (nor this thread... No time atm), but have you got any calls to system.alarm.queryStatus in your ui anywhere? These will absolutely destroy your edt and hence your ui responsiveness. Look for any other scripts calling functions that wait for a gateway response as well. I have my doubts that tag is the culprit. I replaced a huge number of tag expression functions on a page to test this year's ago and found no perceived increase to user experience. (From a system perspective it's still a good idea not to use the however outside of expression tag expressions)

we have a few - just three readbacks to show the total number of alarms on a banner. We'll remove those and see if it helps.

The worst impact of tag() is on window/template startup, with its pathological timeouts per function in the EDT. Once running, it isn't much worse than an indirect tag binding.

I did not read all replies to this post yet, but I have a large project with 800+ OPC-UA connections for a very high variety of objects where none of them are identical.
I use a lot of UDT's for building each object from individual components and each sub-component type has a generic UDT (sometimes two-three) and based on what elements that UDT has or has not, or has enabled or not, my views build themself up accordingly.
I use a way without using any tag() expressions.
To detect if a tag is or isn't present, I use indirect binding to the tag's ".Enabled" property and I have a transform expression on it like

coalesce({value},false)

I have this bonded to the position.display of each individual element that can be (or not) present to a specific component (like a pump).
based on this property, I then enable and do other stuff like activating the proper embedded view by

if({this.position.display},"PathToView",None)

{My Bold}

This is a Vision topic. Vision doesn't have views.

Sorry, my mistake. i finally read the whole post, but even then I did not notice the vision at the top. Sorry again.
Please delete my post if necessary.