How to make window open quicker

Hi,

some of my windows are very slow to open (about 2 to 5 minutes) when it is their first opening. These windows contains many template instances (over a hundred) , and some of them contain more templates inside them.

I tried to reduce the complexity of my heaviest templates because I noticed that they are making the page long to load , but the windows still open too slowly.

I don’t know if it has an impact because I think they run of the gateway, but I use an expression tag in a UDT to drive to color of most my objects. It is the only what I though of to drive my many different templates using the same color patern, so when I would change the pattern I would be easy to do.

I would like to know how can I improve that speed? I can’t reduce the number of object because the window must be the same as the one we used with another software.

Thank you.

You haven’t really provided enough information to solve your problem, and possibly cannot short of posting the project in question for peer review. Large numbers of templates by itself won’t drag a window that badly – I have a project with a dynamic window containing ~ 1000 animated template instances that opens in ~ 10 seconds. Did have problems with it at one point, but it was due to a slow script in a binding (x 1000).
Consider copying the project for testing, stripping all of the bindings out temporarily, and time how fast the window opens. Then start adding bindings back into the templates one at a time, speed testing for each change, until you find the feature that is killing your client. Show us the expressions and/or code for that feature for ideas on better solutions.
Also consider converting the color expression in your UDT to a simple lookup() expression in your display, where the dataset is a static client tag. Such lookup would require no traffic to/from the gateway, and would only be computed for the values in your window that are changing.

I have done some modification on a copy of my initial window. The problem is coming from a specific template.

This template is structured like this:

templateGroup
- 2x template1 (these ones change color)
- 2x template2 (basically a label linked to the template2 name)
- 1 template3 (2 states toggle button linked to a read/write tag)
- 1 template4 (2 states toggle button linked to a read/write tag)
- 1 template5 (a CSV from the Symbol Factory)

The UDT driving template1 contains a string Memory Tag containing about a dozen r,g,b colors and anExpression Tag consisting of many if() function embedded in each other, returning a r,g,b string :
tag: UDT tag
color: r,g,b from the Memory Tag

if (tag,
if(tag && tag=color ,
color,
color),
if (tag,
if (tag && tag=color,
color,
color),
if (tag && tag!=color,
color,
if (tag && !tag,
if(tag!=tag,
color,
color),
if (tag,
color,
if (tag,
color,
if (tag,
color,
if (tag,
color,
color))))))))

template1 “Fill Paint” shape read the UDT tag with toColor() expression function:
toColor(UDT Expression Tag)

I reorganized by copying the original shapes from template1 and template2 directly into templateGroup, so I only kept the original shapes. It seems to accelerate the process, but isn’t enough.

I considered your suggestion of doing the expression in the display. This was the original way I did it, but since I have 8 other templates like template1, which are representations of a straight or round conveyor in all direction, using the display to run the expression forces me to update each template expression seperately when we do modifications to the PLC.

Would it be faster to use a shared/project script instead of the expression, so every template would call that script to get the color. That way I would remove the expression and the memory tag, diminishing the traffic from/to the gateway.

{ Please use a code block the next time you paste something that needs to show indentation. }[quote=“Philcr”]if (tag, if(tag && tag=color , color, color), if (tag, if (tag && tag=color, color, color), if (tag && tag!=color, color, if (tag && !tag, if(tag!=tag, color, color), if (tag, color, if (tag, color, if (tag, color, if (tag, color, color))))))))template1 “Fill Paint” shape read the UDT tag with toColor() expression function:
toColor(UDT Expression Tag)[/quote]Ugh. Does the tag=color part mean you are recursively comparing against the color you’ve computed previously? It didn’t occur to me that you would actually be going directly from booleans to color strings. I typically see this sort of thing resolved to a “state” number and using that in a lookup. Even better if the PLC supplies the unique state number itself. The binEnc() expression function is handy for merging multiple booleans into an integer if that would help you. However you get it, in the application (not in the display, but as client tags in the project), I would have a lookup dataset with state number vs. color. Since you need multiple lookups for different PLCs, I would then have the UDT contain a memory tag with the name of a lookup table client tag. When a PLC changes, make a new lookup table in the project (if a different one doesn’t apply) and change the UDT memory tag.[quote=“Philcr”]Would it be faster to use a shared/project script instead of the expression, so every template would call that script to get the color. That way I would remove the expression and the memory tag, diminishing the traffic from/to the gateway.[/quote]Maybe. The runScript() expression function has high latency if you change the string it executes (because it has to recompile the jython into java bytecode). In v7.7 and before, that was the only way to pass arguments into the script, so runScript() was only really useful for data you couldn’t get any other way, and property change scripts were used in pretty much all other cases. Property changes scripts are great, except when designing, where they only run when in preview mode.
I created objectScript() to beat these problems in v7.7+ – it allows arbitrary arguments after the script string to be passed to scripting without recompiling, among other features. Since v7.8, runScript() can also pass arguments efficiently, but only to custom methods of display components. (I think – I haven’t played with it much.) Anyways, you’d have to arrange for all possible relevant booleans to be passed as arguments to the runScript() expression in order to replicate your logic, which might be OK if you can make it work in a gateway expression tag.

One final note: I don’t pass entire UDTs into window parameters or templates. Yes, I know, there are many IA examples which do so for design convenience and future maintenance. But there are enough forum comments about the poor speed of UDT parameters that I stick with passing a tag path into a template and letting it get the specific values it needs, or doing the binding outside the template. In your case, the template group would be assigned a tag path, and would indirectly bind generic parameters for the nested templates.

1 Like

I can’t only pass an integer to my template because I need the UDT instance name to bind it to a label, and writting the name manually would take too much time.

I am considering the method to pass the UDT instance tag path. Is there a way I can create a string type expression tag inside my UDT that would contains de instance path?

[quote=“Philcr”]I can’t only pass an integer to my template because I need the UDT instance name to bind it to a label, and writting the name manually would take too much time.[/quote]I’m afraid either I don’t understand your application enough, or you don’t understand what I’ve suggested. Please try making your outermost template take a string template parameter that contains the UDT instance tag path, then use indirect binding from that to obtain everything else you need. Use split() on the tag path string to get the last element, the UDT instance name.[quote=“Philcr”]I am considering the method to pass the UDT instance tag path. Is there a way I can create a string type expression tag inside my UDT that would contains de instance path?[/quote]Hmmm. I’ll have to think about that. Not off the top of my head.

So what I did is first creating a string parameter in each of my templates. After that, I created a script inside a button that when pressed, get individually each instance of my templates, get the UDT tag path, put it the the string parameter, than undo the binding to the UDT. Here is the code:

Window = system.gui.getParentWindow(event)
WindowComponents = Window.getRootContainer().components

for Component in WindowComponents:
	if type(Component).__name__ == "TemplateHolder":
		try:
			if Component.templatePath[0:18]=="Equipment/Conveyor":
				Component.Path=Component.Conveyor.getDrivingTagPath()
				Component.Conveyor=NULL
				print Component.Conveyor.getDrivingTagPath()
		except:
			pass

Do you think deleting the UDT parameter would accelerate the loading? I would like to keep it for further use because I will be designing another SCADA with these templates, and I think drag&drop the UDT onto the template is faster to create the windows.

I also tried the split() expression function to get the tag name, but I had to use runScript() to get last row of my dataset. Did I missed an easier way to do it?

Final update, even the indirect binding with a path parameter didn’t work because I need most of the UDT boolean tags (the UDT had about 15, and I needed about 9). As you said previously, binding entire UDT is heavy for the system, and obviously heavier when you pass again that UDT inside embedded templates.

My UDT have 2 integer tags, one from the PLC and one expression tag. My PLCs already give me an integer containing all the boolean, but because I have 3 different types of PLC, so 3 way of encoding the integer, I created an expression tag (integer) in which I encode in a “standard” way my booleans. This way, I can have only one template for every PLC.

To give an idea of the time saved when first opening a window, it took about 2 minutes to open and now it takes less than 10 seconds.

I think this is something IA should talk in their “university” video, since we only realise this at the end of the creation process (after all the structure has been made). Alot of work would be saved that way.

Thank you for you help.