The Vision Client runs on a Java Virtual Machine (JVM), much like the Ignition Gateway. Unlike the Ignition Gateway however, the Vision Client runs on its own separate process from the Gateway and interacts with the Gateway over a Hypertext Transfer Protocol (HTTP) connection. Information regularly travels between the Vision Client and the Gateway, such as keep-alives and the active polling of Tag information through the Client poll rate. Vision utilizes Java Swing for its Graphical User Interface (GUI), which is the backbone of all the components that we can use in Ignition. When a Vision Client is unresponsive, this could be due to a variety of behaviors, such as:
- The Client is frozen. In this state, you are unable to click on any components or navigate between windows.
- Navigation between windows is slow. A new window takes longer than a few seconds to load and render components.
- Updates are slow. Components are generated and displayed quickly, but values are not coming in or updating immediately.
The purpose of this article is to provide some common troubleshooting steps for dealing with performance-related issues with Vision Clients. This article will help you gather relevant information from your Vision Client and the Gateway that can help you resolve the issue.
Identify the Exact Issue You are Encountering
What is the problem exactly? Keep in mind that you’re identifying the issue because you want to understand where this issue is occurring. For example, are they seeing Vision components with overlays? Is the Vision client simply frozen? Is the Vision Client unable to launch or does it crash? Depending on the issue, you can determine whether the suggestions below are helpful for what you are viewing.
Isolate Where the Issue is Occurring and what Subsystems are Involved
The Vision Client being unresponsive while viewing a specific window is different from the Vision client being unresponsive everywhere.
A couple of questions to ask:
- Is this occurring on a single/few clients or all the clients?
- Are there specific windows or components commonly involved when they encounter the issue?
- Which subsystem processes are involved? (Tag History, Alarming, Devices, etc.)
If the issue is specific to a window, then check for a high number of similar components, SVGs/Images, or templates. A high number of components and templates is relative, but typically, similar components on a window are doing similar things and running similar scripts. If one of those scripts is inefficient, then multiplying them by the number of components can make things worse.
SVGs and Images can take up a significant amount of memory to display, and in some cases, they can take a while to load. For example, if there is a 4K resolution image that takes up the entire size of the window, then that could slow the client down.
Depending on the subsystem, you can check the Gateway webpage's log page for any interactions with that subsystem as well as relative sections of the Status and Config sections for additional context.
Break Down the Project Until You no Longer Encounter the Issue
If you suspect there are specific components that are causing issues on the window, do the following steps:
- Duplicate the window
- Remove bindings and delete components from the original window one-by-one
- Observe if the problem still occurs
The idea is that you can gradually remove any noise or unrelated components that makes it difficult for you to isolate the issue. Then, once you've determined what you think may be the cause of the issue, you can manually recreate the window and attempt to reproduce the issue.
If you suspect your issue is a bug, you can share your replication steps and any relevant project exports directly with Ignition support, or you can reach out to the development team and Support department through the Inductive Automation forums. If your issue turns out to be a bug, then your replication steps and project export will be beneficial to determining a fix.
Check For Any Blocking Functions Running Directly in the Client
A blocking function stops script execution until it ends. For example, if you were to use system.tag.writeBlocking in a Button component's actionPerformed event, it will stop executing the script at the line where you ran writeBlocking until the write is completed.
You generally do not want to run blocking functions in a Vision Client, especially if there are multiple such scripts in the Client. As an example, Java Swing’s GUI is generated with a single thread. This thread is called the event dispatch thread (EDT). It is generally bad practice to run blocking scripts in the Vision Client because this can block the EDT.
While there are many areas to run scripts within the Vision client, the most notable is in the extension functions of components. The Button component example mentioned earlier is a single execution, dependent on user interaction. Extensions functions are always running on the component in an open Vision window. If a blocking function runs in an extension function and fails for whatever reason, then this will slow down the entire Vision client because writeBlocking will fail after it exceeds its timeout (which by default is 60 seconds).
If you suspect that the Client is unresponsive due to blocking functions, you can:
- Take 3-5 thread dumps of the Client
- Check the AWT-EventQueue thread
- Confirm if AWT-EventQueue is in either a consistent BLOCKED or RUNNABLE state
Depending on what is blocking the EDT, you should aim to reduce the impact that process has on the EDT, or have it execute on a separate thread entirely using system.util.invokeAsynchronous.
Download Thread Dumps from the Gateway Webpage and the Vision Client Itself (Method Depends on the Ignition Version)
You can take a thread dump from the Vision Client just like you can from the Ignition Gateway. The Vision Client has similar thread dump tools; however, if the Vision client is slow, then it may be difficult to get these thread dumps, since downloading the thread dump is another process that executes on the JVM. In these cases, you can bypass the JVM by running jstack from the operating system (OS) to take the thread dump. Refer to this article for steps on how to take a thread dump.
Check Vision Client Console under Diagnostics > Console
You generally want to look for any errors in the Vision Client that may be related to the issue you are seeing. You should copy and keep relevant stack traces in case you need to reference them later.
Check Client Performance Metrics under Diagnostics > Performance
This may be helpful if there is a high memory trend and the Client restarts. If there is a high memory trend, take a heap dump. Taking heap dumps is beneficial in cases where the Vision Client is closing, because the JVM will shut down if it is unable to get a response from the Client within 30 seconds. The JVM can become unresponsive if it has reached the max amount of allocated memory. Refer to this article for steps on how to take a heap dump.
A heap dump can be also beneficial because you can view the largest objects and largest number of objects in memory at the time that it was high. You can also view the running threads at that time and link them to objects in memory.
Observe Communication between Client and Gateway
You can use Wireshark to observe the traffic between the Ignition Gateway and the Vision Client. Wireshark filtered for 8088 (non-SSL) should be used to capture traffic on the network. If traffic is using Secure Sockets Layer (SSL), then you will not be able to see the messages as they are sent from the Vision Client and received by the Gateway.