reapplyCss() Is called too many times when adding a node hierarchy to the Scene
jerome.p.cambon at gmail.com
Mon Mar 14 11:00:25 UTC 2016
Here are the workarounds I have in mind related to this issue:
1. If the content of the scene graph contains similar nodes after the user action, one could use the Node ‘managed' and ‘visible' properties:
setVisible = false
setManage = false
…. when a node is not needed, and set it again to true when needed.
This allows to re-use the nodes (or hierarchy of nodes) and avoid to re-create them, and also avoid to apply CSS on them (since the nodes are not removed from the scene graph)
2. To avoid to create a bunch of new nodes hierarchy (for instance on each user action):
- When a node (or hierarchy of nodes) is removed from the scene graph, put it in a pool. So you’ll have a set of pool for each type of node (or hierarchy of nodes)
- When such a node is needed, get it from the pool if available
This allows to re-use the nodes and avoid to re-create them (but here the CSS is re-applied, since the nodes are removed/added from the scene graph)
Solution 2 is what we used in Scene Builder, for the Inspector panel.
Since the content of the panel is rebuilt when an object is selected, we had to optimize this.
So we created a set of pools (using Java Stack class) for each Inspector editor (font editor, color editor, style class editor, …).
When an object is selected (from the Content panel), we first clean the Inspector panel and put each editor in its dedicated pool,
then fill it by re-using the editors from the pools. If we need more, we create them as needed.
You can see this in action this by launching Scene Builder:
as you can see, the first display of the Inspector sections are a bit slow, then it becomes quite smooth :-)
Hope this help,
> On Mar 12, 2016, at 2:06 AM, Scott Palmer <swpalmer at gmail.com> wrote:
> Created https://bugs.openjdk.java.net/browse/JDK-8151756
> Please let me know if you find any potential workarounds.
> In my application I had purposely constructed the entire hierarchy before adding it to the Scene to avoid triggering multiple layout passes, but I think that may have also made this CSS issue a bit worse. I did get a ~20% improvement in response time when updating my UI though. In my UI it is possible that on the order of thousands of controls are added or removed from the Scene in response to the user selecting an item. (It’s not usually that many, but sometimes it is.) The delay before the UI updates can be several seconds.
>> On Mar 11, 2016, at 5:33 PM, David Grieve <david.grieve at oracle.com> wrote:
>> There is (was?) some code in Node or Parent that was supposed to prevent this.
>> Namely, I thought I had it so CSS was applied from the parent before applying to the children.
>> It may also depend on how you add the nodes to the scene.
>> On 3/11/16 5:18 PM, Scott Palmer wrote:
>>> I think I've discovered a significant performance issue with CSS
>>> Adding a Node hierarchy to a Scene leads to
>>> javafx.scene.node.setScenes(Scene, SubScene) being called. This leads a
>>> walk down the Node hierarchy like so:
>>> -> invalidatedScenes
>>> -> scenesChanged
>>> -> setScenes // on child Nodes -- recursion
>>> -> impl_reapplyCSS()
>>> loops over children calling reapplyCss() on each - recursive
>>> The thing to note there is:
>>> * invalidatedScenes decides if it is going to call impl_reapplyCSS()
>>> * invalidatedScenes calls scenesChanged which calls setScenes on all
>>> children which leads to invalidateScenes being called recursively on the
>>> node hierarchy
>>> * invalidatedScenes calls impl_reapplyCSS()
>>> As the setScene call walks down the node hierarchy it gets to a leaf node
>>> and then calls impl_reapplyCSS() which will call reapplyCss() recursively.
>>> Since when reapplyCss() returns the cssFlag for the node will be set back
>>> to UPDATE, so when the parent calls impl_reapplyCSS() the CSS is
>>> recursively applied to the Nodes that just had CSS applied!
>>> Am I missing something?
>>> I made a quick test case where I add a VBox containing another VBox
>>> containing a Rectangle to the Scene when I press a button. I can confirm
>>> that reapplyCss() is called THREE times for the Rectangle, twice for the
>>> "middle" VBox, and once on the "top" VBox.
>>> Obviously the deeper the hierarchy the worse this gets.
More information about the openjfx-dev