Startup time optimization
This page is a collection of different steps to reduce the startup time of a Java application converted with CheerpJ.
The CheerpJ runtime is highly optimised to minimise the total download size of an ‘average’ application, totalling 10-20MB of data for a typical download (as a point of comparison, the approximate size of the Java runtime installer is over 60MB). All downloaded components of CheerpJ are cached by the browser, which reduces the download time in subsequent executions of a same application.
This page provides a list of recommendations to reduce the one-time download size, and the resulting application first startup time.
In our experience it is not uncommon to see that most of the loading time is spent downloading the
If you are self-hosting the CheerpJ runtime (most likely you will not), please make sure to enable compression on these components as well. The CheerpJ cloud runtime has compression enabled by default.
Use ProGuard to remove unused code
ProGuard is an industry standard open-source tool to optimize and obfuscate Java bytecode. ProGuard, by itself, can automatically trace the classes used from the application entry point and automatically remove unused classes, methods and field. This can enable a very significant reduction of download size and startup time, especially with applications using multiple third party libraries.
Since Java allows reflection at runtime, ProGuard may end up removing code which is actually used, causing unexpected errors. To help in this scenario CheerpJ supports a special option:
When initialized with this option CheerpJ will keep track of the classes used at runtime, including classes which are accessed via reflection. Follow these steps to safely optimize an application using ProGuard.
- Build a single
uber-JARby merging the application and dependencies
- Convert the new JAR to JS using
- Run the application using CheerpJ with the
- Fully test the application, making sure that all possible scenarios are executed and all needed classes are loaded
- From the browser console call
cjGetProguardConfiguration(), a ProGuard configuration file (
cheerpj.pro) will be automatically generated and downloaded
uber-JARusing the generated configuration file to generate a smaller JAR with only the needed classes.
proguard -dontwarn -injars uber.jar -outjars uber-stripped.jar -libraryjars ~/cheerpj_1.2/rt.jar @cheerpj.pro
- Convert this new JAR using
Reduce the size of the JAR file
cheerpjfy.py supports a command line option (
--pack-jar) to generate a minimised JAR for deployment.
This smaller JAR is stripped of all original Java bytecode and can no longer be used to run the application on the JVM. The JAR is however necessary for CheerpJ to support Java reflection. This optimisation can be used with our without AOT compiling.
It is important to use the same name on your input and output
.jarfiles for your application to work. This action will overwrite your original
.jarfile with the packed one. We recommend backing up your original files somewhere else to keep their state in case you need to use them again.
To use this command you will require to have java installed on your machine.
More details are available here
CheerpJ cannot predict which runtime resources will be required by an arbitrary application. CheerpJ runtime resources are therefore loaded on demand, one after the other, depending on the requirements of the application at run time.
To take advantage of parallel downloads, and reduce download and startup time of a specific application in production, CheerpJ allows to pre-specify a list of resources (CheerpJ runtime modules) to be loaded at startup.
This list of resources is to be specified manually when starting the CheerpJ environment in an HTML page. We also provide a simple profiling tool to automatically record and output a list of used resources during the execution of an application.
By combining the use of this profiler together with the preloader, one can highly optimise the initial download and startup time of a converted application. Taking advantage of this is a simple 2-step process:
The result will look like this:
If the output is not visible fully, you can use:
"), which you should ignore. See here for more information.
- Modify the CheerpJ integration to enable preloading. You will only need to change the
cheerpjInitcall, to pass the
preloadResourcesoption. For example:
See here for more information.
When preloading is enabled CheerpJ will be able to download multiple resources in parallel with the execution of the program. This will greatly improve loading time.