有没有办法快速编译/加载fxml文件只有一次,而不是每次重启应用程序?
我有一个程序,在执行时加载许多fxml文件。 应用程序将在短时间内完成,加载应用程序只需要很长时间。
有许多fxml文件(20+),所有这些fxml文件都加载了Java代码。 应用程序已完成并可以使用,但每次执行程序时都会加载所有文件。 fxml文件只能编译一次,因为完成后它们不会被更改吗?
java代码当然会编译一次,它只是fxml文件。 应用程序现在需要25秒才能启动,加载fxml需要14秒。
有没有办法让这一切更快?
编辑#1:
是否有免费提供的工具可以更快地执行应用程序(Java)? 或者执行时间仅取决于程序的编写方式?
哪种设计模式可以帮助缩短应用程序的执行时间?
编辑#2:
以下代码将简要解释我的问题:
package main; ....... ....... public class MainClass { .... .... List controllerList; public mainClass(List controllerList) { this.controllerList = otherClass.getControllerList(); loadFXMLFiles(); } public void loadFXMLFiles() { for(InformationController controller : controllerList) { controller.loadFXML(); } doOtherStuff(); } .... }
所有这些InformationControllers也加载了其他fxml文件,所以它实际上是一个加载的fxml文件树。 这是在应用程序的每次启动时加载的,所以有没有办法只加载一次这样做?
关于如何加快FXML性能
我会做这个答案社区维基,如果有其他人有进一步的想法,请编辑并添加它们。
- 不应该使用静态
FXMLLoader.load()
而应该创建一个FXMLLoader实例,并使用实例loader.load()
方法重用该实例。 原因是FXML-Loader缓存,例如类查找,因此加载下一个FXML文件的速度更快。 - 使用工具将FXML编译为Java,例如Tom Schindl的FXML编译器或NetBeans FXML到Java转换器 。
- 不要在任何给定时间加载任何超出您需要的FXML,例如,如果您现在不打算显示它,请不要加载它。
- 在后台线程中加载FXML(对于某些控件类型不起作用,例如Java 8中的Tooltip)。
- 首先加载初始登录或启动画面 ,然后在显示启动或登录屏幕时加载其余的FXML。 在登录屏幕接受凭据后,我在某些应用程序中加载FXML。
- 通过删除不必要的节点来降低应用程序UI的复杂性。
- 确保您没有在控制器的initialize方法中对JavaFX UI线程执行不必要的工作(例如,读取数据库)。
- JavaFX 8中的
FXMLLoader.load()
文档包含对FXML模板的引用,但我不认为它曾经实现过,所以它可能对你没有帮助。 - 我听说提到FXML的静态方法很慢。
- 使用JavaFX的最新开发版本 。
- 从FXML加载节点层次结构后,重新使用层次结构,而不是将其丢弃并加载新层次结构(例如,如果您有一个使用FXML构建内容的对话窗口,当用户关闭对话框时,只需隐藏它,何时隐藏它你需要再次显示一个类似的对话框,只显示隐藏的对话框而不是构建一个全新的对话框和场景图。
反思是FXML缓慢的原因
我认为Java 8 FXML实现缓慢的关键原因是它如此依赖于reflection和reflection很慢 ,如reflection教程中所述 :
由于reflection涉及动态解析的类型,因此无法执行某些Java虚拟机优化。 因此,reflection操作的性能低于非reflection操作,并且应避免在性能敏感应用程序中频繁调用的代码段中。