¿Por qué 'Stage # show' es tan lento y qué se puede hacer para acelerarlo?

En JavaFX, la primera vez que se muestra una etapa conStage#show toma mucho tiempo. No estoy hablando del tiempo que lleva cargar FXML (que es un problema completamente diferente), sino simplemente el tiempo que toma entre llamarStage#show y la llamada que regresa (y la ventana que se muestra al usuario).

He creado esta aplicación de muestra, que crea una escena aleatoria con algunas pestañas, paneles de cuadrícula y vistas de tabla, y luego el tiempo que lleva llamarStage#show:

package sample;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.Random;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Speed test");
        primaryStage.setScene(createScene(3, 3, 6, 8));
        long start = System.nanoTime();
        primaryStage.show();
        long end = System.nanoTime();
        System.out.println("Total seconds: " + ((double) (end - start)) / 1000000000);
    }

    private Scene createScene(int tabs, int rows, int columns, int tableColumns) {
        TabPane tp = new TabPane();
        for (int t = 0; t < tabs; t++) {
            GridPane gp = new GridPane();
            for (int r = 0; r < rows; r++) {
                for (int c = 0; c < columns; c++) {
                    gp.add(getRandomControl(), c, r);
                }
            }
            TableView<Object> tv = new TableView<>();
            for (int i = 0; i < tableColumns; i++)
                tv.getColumns().add(new TableColumn<>(getRandomString()));

            VBox vb = new VBox(gp, tv);
            tp.getTabs().add(new Tab(getRandomString(), vb));
        }
        return new Scene(tp);
    }

    private final String[] randomStrings = new String[]{
            "foo",
            "bar",
            "baz",
            "lorem",
            "ipsum",
            "dolor",
            "sit",
            "amet",
            "adipiscing",
            "elit",
            "morbi",
            "quis",
            "tempus",
            "justo",
            "faucibus",
            "justo",
            "risus",
            "nec",
            "commodo",
            "sem",
            "congue"
    };

    private final Random random = new Random();

    private String getRandomString() {
        return randomStrings[random.nextInt(randomStrings.length)];
    }

    private Control getRandomControl() {
        switch (random.nextInt(4)) {
            case 0:
                return new Label(getRandomString());
            case 1:
                return new TextField();
            case 2:
                return new PasswordField();
            case 3:
                ComboBox<String> cb = new ComboBox<>();
                cb.getItems().addAll(randomStrings);
                return cb;
            default:
                return null;
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}

Mis resultados varían, por supuesto, pero siempre son alrededor de 1.2 segundos, lo que no parece mucho, pero ciertamente es notable, y no demasiado esperado, considerando que mi máquina carga interfaces de usuario comparativamente complejas en una fracción de este tiempo (como siempre que no estén escritos en JavaFX, eso es).

Entonces mi pregunta es: ¿qué causa este bajo rendimiento? ¿Hay algunos trucos o trucos para minimizar este tiempo, similar a lo que se hace para acelerar la carga de FXML?

Respuestas a la pregunta(0)

Su respuesta a la pregunta