Perspective screen draw time

I have a perspective application where some screens contain a lot of components. In those cases, the screen redraw seems to take a long time, with individual components showing "invalid/red" before their underlying data gets linked in.

For instance, I have a screen for maintaining recipes on a several machines. The recipes are stored in each PLC (Rockwell ControlLogix) as an array of 1000 UDTs. Each UDT contains around 40 to 80 items (strings, ints, floats, bits) depending on which machine I'm editing. Within the recipe, items are broken down into various groups (heat, quench, temper, etc). The editor screen displays the recipe as an accordian container which allows the user to expand or contract groups for easier editing. Each section of the accordian contains a flex repeater. Each element of the flex repeater displays one recipe item.

Because the recipe for one machine does not necessarily match the recipe for another machine, the recipe screen has to be built programmatically using JSON. I build the JSON in a local variable within the script, then assign the value to the accordian property.

What happens next is the part I'd like to speed up. RIght now I can watch each element of the accordian draw, invalidate, and validate. The screen looks to be in constant motion for a couple of seconds while this is all happening.

Is there any way to get the screen to look a bit more crisp? In my MS Visual Studio projects I can enable double buffering, then prevent the screen from redrawing until the all the screen elements are updated. This way, the screen doesn't flicker or populate until the whole screen is ready to be viewed.

I'm probably missing something that's already in perspective, but any suggestions would be appeciated!

1 Like

It's hard to say for certain without seeing the finer details of what you're doing. I have a couple optimization tips that may be applicable.

If you're doing tag reads in your script you want to minimize the number of reads you're doing by reading blocks of tags in a single tag read statement.

If possible, you want to use indirect tag bindings instead of expression bindings to populate values. Sometimes you can see a significant performance improvement by adding custom properties to a component and indirect binding it to tag values through a parameter-driven indirect tag binding. Binding 80 tags without indirect bindings could definitely cause a performance impact.

Steve - Thanks for the reply!

Great idea about the indirect tags. I'll give that a try and report back.

Regarding tag reads - I try to use the the tagReadBlocking or Async methods whenever I have even just 2 tags to read. I've noticed significant performance improvement with that.

I'm getting off my topic category here, but one of the tasks in this project is to back up all PLC recipes (1000 of them) to the database and be able to restore them back to the PLC (in case the PLC had to get changed out). I use a parameterized UDT where I pass in a specific recipe number, wait for the UDT to populate, then write the values to the database. REALLY slow. It's an AllenBradley ContolLogix PLC which doesn't natively support OPC-UA - so I can't read the PLC UDT as a block and parse the resulting JSON. Instead, the Ignition reads individual tags to populate the equivalent Ignition UDT. There is some optimization by the OPC server, but it's still really slow.

Part of that also stems from reading a single recipe at a time. The parameterized UDT takes in the index of the PLC UDT. So basically I read Recipe[0], then Recipe[1], etc. The OPC server takes about 8 seconds to re-register and re-scan the UDT tags whenever I change the index parameter. Haven't found any way to speed that process up yet. 1000 recipes @ 8 seconds per = 8000 seconds or about 2.5 hours. I've written VB applications that can read the same recipes in under 1 minute. Again, seems like there's a better way out there....

Thanks again, for the tips!

For storage of recipe data from plc, don't subscribe to the tags, but instead use direct OPC reads/writes. System.opc.readBlocking.
You need to then provide the opcitempaths for these. This will be infinitely faster


What Nick said, but you also might want to play with the beta of my new driver:

It optimizes direct OPC reads too, not just subscriptions. Be sure to use a single OPC read that lists every element of all 1000 array subscripts.

You have a couple of good responses that I think are worth checking out.

I would add that the firmware of your Rockwell PLC is also very relevant to performance of the Ignition AB drivers. If you're on the edge of where Rockwell patched a security issue you can see really slow performance on tag updates with the official AB drivers. If memory serves version 20.19 requires the new Ignition driver (for versions 21+) and has slower performance. 20.18 requires the legacy driver and performs very slowly.

Definitely check out the @pturmel driver if you're in that situation because he is doing things that the Ignition developers will not because they restrict their driver to the official documented OPC-UA interface which is slower than the interface Rockwell uses behind the scenes with their own products. For example, Linx Enterprise is not an OPC server. At least that's my understanding which is admittedly surface level.

That's not quite right. IA restricts itself to implementations using publicly available protocol documentation. Some radicals are prepared to look under the hood (at packets) to figure out faster options.

Linx Enterprise is indeed an OPC Server. It just takes advantage of Rockwell's proprietary information to go faster than anyone else.

Thank you for clarifying. I tagged you in case I was misstating anything.

I had a Rockwell technician tell me Linx Enterprise is not an OPC server which is why they call the topics shortcuts so I was reiterating what they told me. I think of it as an OPC server regardless. It's probably branding to explain why 3rd party OPC connections to their devices are slower. Like the branding with PLC/PAC (lol).

Thanks Phil and Steve - I'll be testing the OPC read (vs Tag read) over the weekend.

I'll also give your driver a test run, Phil. I'm a bit of a radical as well! My PLC is running firmware version 32 (customer requirement). Over the years I've noticed a steady performance slowdown as Rockwell has been attempting to add security to the EIP and TCP drivers. I'm more of a fan of letting the PLC run at flank speed and add the security to the network side. Keeps the IT folks busy (!!).

Your indirect tag suggestion worked great for the screen refresh, Steve. Still get a momentary flicker but it's a whole lot faster! I also got rid of as many bindings as possible (enabled, min/max input bounds, etc) on all of the displayed fields. I update those same fields in script on a single binding.
Significant improvement from that, as well.

Thanks again! I'll post results after this weekend's testing.

So, some results:

I limited the bulk read to 100 recipes. Trying all 1000 generated a script fault for memory.

Each recipe is 39 tags for this trial, for a total of 3900 tags.

Using subscribed tags, 1 recipe at a time (parameterized UDT): 820 seconds
Using OPC readValues() 1 recipe at a time: 70 seconds
Using OPC readValues() 100 recipes at a time: 23 seconds

So, if my math is correct, thats 230 seconds or just under 4 minutes for all 1000 recipes. Compared to 2.5 hours.

WOW! Amazing results! Kudos to Steve and Phil for their insight!!

Note: I did not try bulk reading 100 subscribed recipes. Adding 3900 tags to the server doesn't make a lot of sense for a feature that will only be used on user request. Some of the machines I'll be backing up have upwards of 200 elements per recipe. So the tag count and time just keeps multiplying.

Huh. Seems painfully slow to me.

Is the Ignition gateway in the cloud while the PLC is in the plant? If so, that can slow you down 10x or 20x or more.

Yes. Cloud based.
Which I'm not a fan of by any means. Plant based system with a link to a cloud based system, seems bit better. I'm having some difficulty convincing my customer. But I'm gaining more credibility as I get the IT department more onboard.... The old story....

But, I quick update to my update. Minor tweaks to my script got the full 1000 (39000 tag) backup completed in just under 10 seconds. Turns out I had a loop in a loop that was totally unnecessary. (Maybe it's time to retire! My senility is starting to show.)

Thanks again for all the help!