Greetings, I hope everyone is doing well. I’m running into a performance / stability issue with the Flex Repeater component.
Our server is running the Perspective module version 1.0.9 (b2020021812).
NOTE: To preface this, the saved & committed view renders okay in the browser, with none of the troubles I see in the Designer appearing to be present.
NOTE: I’ve tested this in both the Linux and Windows variants of the Designer with identical results
The behavior in the designer, loosely speaking, goes something like this: Whenever the view is loaded or reloaded, components tend to throw errors about the maximum call stack being reached:
[Browser Events Thread] INFO Perspective.Designer.BrowserConsole - RangeError: Maximum call stack size exceeded [Browser Events Thread] INFO Perspective.Designer.BrowserConsole - ui.ErrorBoundary: Component error caught in error boundary: undefined
I observe 3 possible states that the view can load with:
- The view will load with some of the embedded views in the FlexRepeater not loading correctly, and some of them displaying normally, never randomly dispersed. The embedded views at the top, (presumably the views loaded first) are in an error state and the bottom (presumable the more recently loaded views) are displaying normally.
To reiterate, this is behavior seen exclusively within the Designer.
The alternate behavior to this is having the embedded views show in an error boundary state, but I can still deep select components
The worst state is having the entire view in an error boundary state, or similar to the 2nd state described. Attempting to deep select any other component fails and no actions can be taken on that view currently being edited. Attempting to toggle the view between preview / design mode does nothing as well. On closing the view through the designer, I get this exception in the designer console (With the gateway log indicating nothing unusual):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at com.inductiveautomation.perspective.designer.workspace.ViewWorkspace$Actions.updateDeepSelectionToolbar(ViewWorkspace.java:654) at com.inductiveautomation.ignition.client.util.EDTUtil$ProcessQueue.run(EDTUtil.java:127) at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.EventQueue$4.run(Unknown Source) at java.desktop/java.awt.EventQueue$4.run(Unknown Source) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
The targeted embedded view has:
38 property bindings, no transformations
1 binding with a script transformation
The params to the view are all inputs.
One input param has a change script that calls a custom method on the root component, which has a script that looks like this:
def updateDisplay(self): if self.view.params.display == False: self.view.props.defaultSize.height = 0 self.meta.visible = False else: self.meta.visible = False if self.view.params.variable == 0: self.getChild("child1").position.display = True self.view.props.defaultSize.height = 78 self.getChild("child2").getChild("child1").getChild("child1").meta.visible = False else: self.getChild("child1").position.display = False self.view.props.defaultSize.height = 39 self.getChild("child2").getChild("child1").getChild("child1").meta.visible = True
With my testing I have 31 instances defined in the flex repeater (The instance objects are never dynamically created, the object structures are static), which means it has to evaluate 1178 bindings in 31 separate views, with each view running the above script on their own view on load. To me, this is probably a bit much for the server / client framework to handle at once but I don’t think I’ll be the last person attempting this sort of feat with Perspective.
I’m researching different avenues to workaround this shortcoming, but I thought it would help to share my findings so that perhaps the Flex Repeater can be more useful in the future.