On Mon, 7 Sep 2026 13:24:05 GMT, Marius Hanl <[email protected]> wrote:

>> This PR is an optimization for `Node.styleClass` and `Parent.stylesheets`.
>> Instead of always initializing both properties with an empty list, we are 
>> creating (therefore allocating) the list on the first access instead.
>> Similar to many other lazy properties.
>> 
>> Why?
>> - `Parent.getStylesheets()` is very rarely used by developers and JavaFX 
>> code. So this list is very often completely unused and empty. Most 
>> developers usually only add stylesheets at the `Scene`
>> - `Node.getStyleClass()` is usually not used (empty) for layout containers 
>> such as `Pane` or `Group` or shapes. A JavaFX App usually consists of a good 
>> amount of such containers (or shapes)
>> 
>> So that our CSS code is not initializing both lists on access, I added 
>> related `NodeHelper` and `ParentHelper` methods to return `null` when both 
>> lists were not initialized and therefore used. Otherwise we return the list 
>> as before.
>> This will save us some memory and allocation, which is both good for the 
>> memory consumption but also for `Node` / `Parent` creation (time).
>> 
>> Added documentation and tests. Will do some measurements with some apps very 
>> soon and attach it here.
>> 
>> ---
>> 
>> # Benchmarks
>> 
>> I wrote a very small scene graph analyzer snippet to measure the memory gain.
>> Feel free to test this on your own apps!
>> 1. Get the `SceneGraphAnalyzer` here: 
>> [SceneGraphAnalyzer](https://gist.github.com/Maran23/38beca5b043e547e1a84749e3162c0b2)
>> 2. Add this code to your `Scene` and press the shortcut `F12` when all of 
>> the UI is loaded:
>> 
>>         scene.setOnKeyPressed(event -> {
>>             if (event.getCode() == KeyCode.F12) {
>>                 var analyzer = new SceneGraphAnalyzer();
>>                 var res = analyzer.analyze(scene);
>>                 res.print();
>>             }
>>         });
>> 
>> 3. If you have a modular app, add the following VM argument: `--add-opens 
>> javafx.graphics/javafx.scene=yourapp`
>> 
>> ## Projects
>> 
>> 1. Tested with 
>> [JFXCentral](https://github.com/dlsc-software-consulting-gmbh/jfxcentral2)
>> 
>> 
>>   +---------------------------------------------------------------+
>>   | Scene Graph Analysis                                          |
>>   +---------------------------------------------------------------+
>>   |  Nodes: 654 total, 388 parents, 266 leaves                    |
>>   +---------------------------------------------------------------+
>>   |   Field         Null   Total       %    N/A    Avg      Saved |
>>   |   ------------------------------------------...
>
> Marius Hanl has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Use String.join

modules/javafx.graphics/src/main/java/com/sun/javafx/css/StyleManager.java line 
1638:

> 1636: 
> 1637:                     final String styleClass = styleClasses.get(n);
> 1638:                     if (styleClass == null || styleClass.isEmpty()) 
> continue;

please use curly braces and place continue on its own line

modules/javafx.graphics/src/test/java/test/javafx/scene/NodeTest.java line 112:

> 110:     public void setUp() {
> 111:         toolkit = (StubToolkit) Toolkit.getToolkit();
> 112:         stage = new Stage();

1. many other tests do `((StubToolkit) Toolkit.getToolkit())` so it probably 
makes sense either do the same, or fix the other test to use this reference
2. this Stage is being created for each test, but only used it in one, is this 
right?

what do you think?

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/2191#discussion_r3961781386
PR Review Comment: https://git.openjdk.org/jfx/pull/2191#discussion_r3962218699

Reply via email to