Using Code Optimization Software to reduce the size of JavaFX Applications

You may increase the efficiency of your Java applications by applying some optimization methods on the Java byte-code. Shrinking and obfuscation are commonly used for this purpose. Shrinking is the process of removing unused classes, methods and fields, resulting in the processed byte-code having smaller size. Obfuscation is primarily used to make the code harder to debug and reverse-engineer. As an additional feature, obfuscation also reduces the size of the byte-code, since this process replaces the identifers in class files with shorter ones.

Reduction in the size of byte-code often implies an improvement in load time. Applet developers could especially benefit from such optimizations, since the transfer of compiled code accross a network is an important bottleneck.

In this article, I will show the use of optimization methods on a sample JavaFX application. I will use ProGuard 4.5 as the optimization tool. I choosed this tool, because it is available under the GPL free licence, easy to use and has a few more additional features than the other options out there. For more information about ProGuard, please see http://proguard.sourceforge.net/ .

Here is the JavaFX code:
package test;


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
import java.applet.Applet;
import javafx.scene.layout.VBox;
import org.apache.tools.ant.taskdefs.Concat;
import org.apache.tools.ant.taskdefs.Cvs;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.taskdefs.GZip;
import org.apache.tools.ant.taskdefs.Length;
import org.apache.tools.ant.taskdefs.Move;
import org.apache.tools.ant.taskdefs.SendEmail;
import org.apache.tools.ant.types.resources.selectors.Date;

// Create some random objects which reference the Ant.jar
var objList = new java.util.ArrayList();
objList.add(new Concat());
objList.add(new Move());
objList.add(new Cvs());
objList.add(new Delete());
objList.add(new GZip());
objList.add(new Length());
objList.add(new SendEmail());
objList.add(new Date());

for(obj in objList){
println(obj);
}

var startTime = FX.getArgument("startTime");
var loadTime = 0.0;

try { 
var endTime = java.lang.System.currentTimeMillis();
var startTimeL = Long.parseLong(startTime.toString());
loadTime = (endTime - startTimeL);
} catch (e : java.lang.Exception) {
e.printStackTrace();
}

Stage {
scene: Scene {
width: 400
height: 250 
content: [
Text { content: "Load Time: {loadTime} ms"
y: 150 x: 100 font: Font { size: 25 } }
]
}
}

The only task this code carries out is to create some random objects referencing the Ant library. This may not mean much for an applet, but the purpose of this example is to demonstrate the difference between the load times of optimized and non-optimized byte code. Now, since we have references to ant.jar file from JavaFX code, we may expect a faster loading time after making some optimizations on ant.jar. Here are the steps to follow:
  1. Download the ProGuard distribution and extract it to a location on your computer.
  2. Run proguardgui.bat which resides in ${PROGUARD_HOME}\bin directory. This will open ProGuard in graphical mode. (When you click the buttons in the menu on the left side, appropriate pages will be opened to allow you make configurations.)
  3. Input/Output configuration: As input, we need to add the ant.jar file, since this is the one we want to process. We also need to specify the output path to which the ProGuard will generate the final jar. In the libraries section, ProGuard allows us to specify referenced libraries. Java runtime library is added in this section by default, so we don't need to make further changes here.
  4. Shrinking configuration: We may specify which classes to shrink or keep at this page. In our case, we should keep the classes that is referenced from JavaFX. Down at the page, the section titled “Keep additional classes and class members” allows us to do that.
  5. Obfuscation configuration: Similar to the shrinking step, we should keep the JavaFX referenced classes from being obfuscated.
  6. I did not make any changes in Optimization Page. Finally, I had to check “Ignore warnings about possibly erronous input” box in Information Page, since ProGuard could not produce the output jar without this option checked. In our example, this change does not cause any problems, however you should be careful with this option when you are working on your own projects.
  7. Now that we made the necessary configurations, we are ready to process the file. Clicking on the Process button on the Process page will produce the output jar for us.
Let's compare the size's of the original (input) ant.jar file, and the processed (output) ant.jar file:
   
    Original:    1.476 KB
    Processed: 300 KB

As you can see, there is a significant reduction in the size of jar file.

You can download the source code and binaries from here. When you extract the downloaded package, you  will see two folders named as optimized_test and nonoptimized_test. You can compare the load times by opening Main.html files in these folders. Please note that, you should clear the Java cache between consecutive executions of the JavaFX application. Otherwise, the results will not be healthy.

Below are my results of load time comparison :

Internet Explorer 8.0Google Chrome 5.0
Non-Optimized1045 ms1250 ms
Optimized776 ms958 ms

My system properties are:
Processor: Intel Core 2 Duo T9550 2.67GHz
Operating System: Windows 7 Ultimate 32 bit
Memory: 3 GB


Yücel Ünlü

Comments

Popular posts from this blog

Powerful Free Webinar Network for Oracle Developers

PL/SQL Developers! Formspider 1.9 is Out