Entering your website into the brilliant PageSpeed tool offered by Google you may find that one of the issues it highlights is related to "Optimize images". Clicking into this section will present you with a list of images that Google suggests can be optimised by lossless compression, offering the size of reduction per image, which is useful for showing which images to focus on. There are many image compression tools available, the tool I am going to use is Yahoo! Smush.it, a free to use lossless image optimization tool. Smush.it is available online and is easy to upload images or enter URLs and then obtain a zip of the images. This isn't very efficient if you have a large quantity of images or if you continually update images. The efficient way of tackling this task is by using automating the process via a build script.
Ant is a popular build tool that I use throughout all personal and work projects in order to prepare a project for production environment. Ant is great for running command line tools whether a .jar or .exe so in order to automate Smush.it I would need to find a command line version. Thankfully someone has created an open source project hosted on bitbucket that does exactly that and is perfect for automation. This command line tool is great as it can optimize all images in a specified folder and any sub folders that match the specified image formats. The command line tool simply uploads the images in the specified directory to the online Smush.it tool and then downloads the optimized images which will replace the original image if there is any reduction. This does mean that the machine that is running the Ant build script must be connected to the Internet in order for this to work.
The command line tool accepts a handful of arguments that are documented in a blog post on the creators website. The only mandatory arguments is -imageDir, which specifies the directory whose images will be processed. The other arguments that will be used in the example is -imgExtensions and -verbose. -imgExtensions aids in filtering the images that are processed, allowing you to specify a comma separated list of file extensions that should be processed. -verbose is followed by a boolean that indicates whether detailed messages will be outputted. These messages do provide a useful summary of the whole optimization is provided notifying the total images processed, how many of these were reduced and the total percentage of reduction that occurred.
In order to implement this into a build script you need to download the latest version of the command line tool (currently v0.3 at the time of writing). Unzip the download and copy "smushit.jar" into your project (personally I have a separate directory in the project for the build, which has a tools directory). The next step is to add a new target to the build script that will be responsible for compressing the images using the command line tool. The target will consist of the java task that is capable of running the smushit.jar file with some custom options. The code below shows the example target responsible for running the smush.it command line tool.
<target name="-optimiseimages"> <java jar="/tools/directory/smushit.jar" fork="true" failonerror="false"> <arg value="-imageDir=/my/images/directory/"/> <arg value="-verbose=true" /> <arg value="-imgExtensions=png,jpeg,jpg" /> </java> </target>
The target above will use the smushit.jar in order to optimize all the PNGs and JPEGs inside the "/my/images/directory/". The fork attribute on the java task must be set to true, otherwise Ant throws this error message, "Cannot execute a jar in non-forked mode. Please set fork='true'". In this example I have set failonerror to false, because if the machine doesn't happen to be online or the connection fails I don't really want this to fail the build because it isn't really a show stopper.
That's it! When I performed this on the images on my website there wasn't much reduction due to the lack of images, however running on the Moov2 website lead to a 7% reduction, and also meant that PageSpeed no longer recommend any suggestions for optimizing images. If you would like to see how this fits with an entire build script for a website then check out the build script for the theme for my website.