Why is `Stage#show` so slow, and what can be done to accelerate it

淺唱寂寞╮ 提交于 2019-12-31 02:51:05

问题


In JavaFX, the first time a stage is shown with Stage#show takes a long time. I'm not talking about the time it takes to load FXML (which is a different issue altogether), but simply the time it takes between calling Stage#show and the call returning (and the window shown to the user).

I have created this sample application, which creates a random scene with a few tabs, grid panes and table views, then times how long it takes to call Stage#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);
    }
}

My results vary, of course, but they are always around 1.2 seconds, which doesn't sound like a lot, but is certainly noticeable, and not too much expected, considering my machine loads comparably complex UIs in a fraction of this time (as long as they're not written in JavaFX, that is).

So my question is - what causes this poor performance? Are there some tricks or hacks to minimize this time, similar to what is done to accelerate FXML loading?

来源:https://stackoverflow.com/questions/35214022/why-is-stageshow-so-slow-and-what-can-be-done-to-accelerate-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!