mgarin / weblaf

WebLaF is a fully open-source Look & Feel and component library written in pure Java for cross-platform desktop Swing applications.
http://weblookandfeel.com
GNU General Public License v3.0
1.13k stars 234 forks source link

Extremely long initialization time under specific OS and JDK versions #594

Open mgarin opened 4 years ago

mgarin commented 4 years ago

This have been reported by @kovadam69 on Gitter:

WebLookAndFeel.install(); takes 27 seconds to finish

I'm on Ubuntu 19.10, using Cinnamon desktop (xorg), JDK: 1.8.0_171, oracle, X64, kernel: 5.3.0-23-generic

Core i5 CPU, 16Gb RAM and a 512GB Samsung 960 PRO SSD

I tried it now, with OpenJDK 13 it starts in 4 seconds, with Oracle JDK 1.8.0_171 starts between 28-30 sec. With IntelliJ it even starts a bit faster than normal. Strange. I do not use any VPN or any Proxy on my computer.

sometimes it's stucking at some GTKStyle @ nativeGetXThickness

Using your suggestion seems, that the 3 sec loading time is constant even on multiple start (from intellij idea with debug)

What if you try NativeFonts.setUseNativeFonts ( false );?

This seems like another JDK-specific bug, seems to reproduce only on JDK 8 and only under specific Ubuntu/desktop version.

Sciss commented 4 years ago

I did get reports about strong startup slowdown, after changing from 1.29 to current versions. And indeed even on my quite fast computer I notice that startup takes significantly longer. My guess is this all related to the XML parsing. In both cases it's AdoptJDK 11, once on Mac, once on Linux

mgarin commented 4 years ago

There are a few things at play there, between v1.29 (old one) and v1.2.9 (or any newer ones):

  1. There have been a major increase in amount of styles that are loaded in each skin, it pretty much went from like 20-50 styles to 1000+ styles which certainly makes initialization slower on startup.

  2. Reading XML files certainly takes longer with more files & styles to read, but doesn't take majority of the time, not even close actually. I would say it's around 15~25% of the load time on average or less with a semi-decent SSD.

  3. Majority of the initialization time is taken by the code that compiles all styles that are read from the XML into their final form that is used in runtime. A lot of stuff is involved in that part and it sure takes a while with a 1000+ styles that extend each other.

  4. The time taken by (3) part heavily depends on JDK version and can vary a lot. On fast machine with JDK 8+ you might load everything in under a second, while on slower machine with JDK 6 it will take up to 6~18 seconds.

  5. On top of the previously mentioned things - there seem to be a few issues related to some specific systems/JDK versions that are quite hard to reproduce. Like the one mentioned in this issue and one from #499. These seemingly appeared with v1.2.9 and v1.2.10 where I have introduced a better usage of native OS fonts which was basically taken from existing native L&F implementations and can be found in NativeFonts class at the end.

Now regarding possible improvements:

  1. I can't do much about the amount of styles - it's just too convenient to have a lot of them available. Plus most of them are used by various WebLaF components. There shouldn't be too many coming in the future as I've already ported most components to styling support, but there will be some.

  2. I already tried some different approaches to loading skins, but none really gave any big advantage in time. So this part will probably stay as it is - just reading skins & styles from XML through XStream.

  3. I already have plans to reduce compile time to zero in the next update, I mentioned it on performance topic but I've separated it now into a new issue: #595. Basically it will all be lazy. So instead of compiling 1000+ styles at start it will lazily compile them 1 by 1 as application requests them. This should reduce WebLaF initialization time down to XML reading time, probably around 100\~300ms depending on your hardware. And it shouldn't affect runtime performance at all because single style compilation time is often less than 1ms, so even if you will be creating a big UI piece - you will probably hit 20\~30 styles at most, adding just a tiny bit of processing time.

  4. Can't do much about JDK - it's up to you to use newer ones if you want to achieve better performance. It seems to be true that every newer JDK yields a slightly better initialization time.

  5. This part is tricky and I can't really do much about it either unless I am able to reproduce the bug and it is actually on WebLaF side and not in some native code. Disabling native fonts and providing custom ones might do the trick as a temporary solution for specific OS and Java version if you're encountering those problems.

Hopefully this clarifies it a bit.

There can of course be some other issues that I haven't noticed, but so far the increased init time was within expected range because of all the styles added in new versions.