PNG Image Optimization for Reduced File Sizes

June 28th, 2009 Alex Moffat

Inspired by the third part of Stoyan Stefanov’s series about Image Optimization I decided to see what I could do with the PNG images in Blueprint. Stoyan suggests four possible programs to use, pngcrush, pngrewrite, OptiPNG and PNGOut. I was unable to compile pngrewrite so I ended up with three possibilities which I tried on all of the files to see how they performed. It turns out, that for our images at least, there is no clear winner, some files compress better with one program and others with another. The best any individual program could achieve was an overall reduction of 12% across all the files while picking the best program for each file produced a reduction of 17%.

  Total size of original files 133368 bytes.
  0 files could not be reduced in size.
  pngcrush
    If used as only reducer saves 14887 bytes = 11%.
    Was the best method for 68 files, saving 9943 bytes.
  OptiPNG
    If used as only reducer saves 13742 bytes = 10%.
    Was the best method for 1 files, saving 163 bytes.
  PNGOut
    If used as only reducer saves 17148 bytes = 12%.
    Was the best method for 16 files, saving 13789 bytes.
  Maximum possible reduction 23895 bytes = 17%.

Out of interest I ran the test again over the optimized files to see if further reductions could be obtained, for instance if OptiPNG could further reduce a file that pngcrush had reduced.

  Total size of original files 109473 bytes.
  68 files could not be reduced in size.
  pngcrush
    If used as only reducer saves 50 bytes = 0%.
    Was the best method for 2 files, saving 48 bytes.
  OptiPNG
    If used as only reducer saves 162 bytes = 0%.
    Was the best method for 15 files, saving 151 bytes.
  PNGOut
    If used as only reducer saves 0 bytes = 0%.
    Was the best method for 0 files, saving 0 bytes.
  Maximum possible reduction 199 bytes = 0%.

The answer apparently is that you really don’t get any worthwhile size reduction from a second pass.

Originally I wrote a Ruby program to run these test, after all everyone knows Java is no good for invoking command line programs! Well, that’s not true. After getting the Ruby version working in a basic way I switched over to Java. With a decent IDE I can write Java faster than I can write Ruby and Runtime.getRuntime().exec() is a great way to run command lines. I even included some gratuitous use of ExecutorCompletionService from java.util.concurrent to be able to run the optimizations for each file in parallel.

Posted in Web | No Comments »

Gadget Robot communication in Google Wave – Theory and Practice

June 21st, 2009 Alex Moffat

In Google Wave gadgets run in the browser and are the main way for 3rd parties to add additional UI to waves. Gadget have very limited access to the contents of the waves they are added to, being able only to see and modify a collection of property values that represent the state of the gadget. Robots on the other hand run on the server, in fact just the Google App Engine at the moment, and act as automated participants in the wave, able to do many of the same things human participants can. It’s also possible, in theory, to combine the two extensions and have robots and gadgets communicate with one another. In practice there are still a few problems with the actual implementation, as you can see in the video below.

Read more below the cut about how this was implemented.
Read the rest of this entry »

Posted in Google Wave, Java | No Comments »

Wave Gadgets with GWT – Build improvements

June 10th, 2009 Alex Moffat

I’ve found a couple of things to make the process of building a Google Wave Gadget with GWT easier. In my previous post on Building a Google Wave Gadget with GWT I used a script element in the GWT module.xml file to include the wave.js file and I created a NeedsRpc interface to generate the <Require feature=”rpc”/> element in the ModulePrefs. There are easier ways to accomplish both of these tasks using the Google API Libraries for Google Web Toolkit but they are not very well, if at all, documented.

To include the wave.js script it’s better to use the @Gadget.InjectContent annotation. This will add the content of one or more files to the top to of the Content element in the gadget xml file. I added @Gadget.InjectContent(files={”ModuleContent.txt”}) as an annotation to the HelloWorld class. ModuleContent.txt contains <script type=”text/javascript” src=”http://wave-api.appspot.com/public/wave.js”></script>. Adding the wave.js script in this way also solves the problem I was having with wave.isInWaveContainer() always returning false. It must have been the result of an initialization order issue.

A similar technique can be used for the ModulePrefs. Adding @Gadget.InjectModulePrefs(files = {”ModulePrefs.txt”}) as an annotation, also to the HelloWorld class will add the contents of ModulePrefs.txt into the ModulePrefs element. ModulePrefs.txt contains <Require feature=”rpc”/>. The final result is

@Gadget.ModulePrefs(title = "Hello Wave World")
@Gadget.InjectModulePrefs(files = {"ModulePrefs.txt"})
@Gadget.InjectContent(files = {"ModuleContent.txt"})
public class HelloWorld extends Gadget {

with no need for extra interfaces or dummy methods and the correct initialization behavior.

Posted in GWT, Google Wave | 5 Comments »

Building a Google Wave Gadget with GWT

June 7th, 2009 Alex Moffat

I’ve just written my first Google Wave Gadget using GWT with the Gadgets portion of the Google API Libraries for GWT. You can see it in action in the video below. I’ll describe how I got this to work and talk about the source code below the fold. The complete source for this example Wave Gadget can be downloaded.

Read the rest of this entry »

Posted in GWT, Google Wave, Java | 3 Comments »

GWT HashMap: FastStringMap No More

June 5th, 2009 Damon Lundin

In my last post about using HashMaps in GWT, I concluded that you would be better of using the FastStringMap that is part of GWT.  I decided to re-run my tests now that GWT 1.6 has been released to see what we get.  The bottom line is that you can now use a HashMap and stop using the FastStringMap.

Read the rest of this entry »

Posted in GWT | No Comments »

Graceful shutdown for Jetty

June 3rd, 2009 Alex Moffat

Jetty has a graceful shutdown option that gives in progress transactions a chance to complete before the server stops. I got this working when running jetty from the maven-jetty-plugin by adding <Set name=”gracefulShutdown”>3000</Set> to the jetty xml configuration file but it just wouldn’t work when using start.jar and a war file with the same configuration. A bit of digging around in the jetty Server source shows that there’s another property you have to set as well, called stopAtShutdown. I added <Set name=”stopAtShutdown”>true</Set> to the configuration and all is now fine. If you look at the source for the plugin you can see the line this.server.setStopAtShutdown(true);, which shows why the plugin works without the additional config. Frustrating.

Posted in Java | No Comments »

Using community equity to attract and develop talent

June 1st, 2009 Lisa Dyer

This past year, the Information Development team at Lombardi has been thinking a lot about community equity, and the powerful role it can play in attracting and developing talent. I think this is especially topical with our recent launch of Lombardi University.

Active community participation is clearly a good goal, but it’s been difficult to measure. To quote OnDemand Beat: “There are a number of arbitrary measurements that Enterprise 2.0 solutions providers and end users have cobbled together but up until recently there has not been a tried and proven method to calculate community participation.”

Here’s a quick look at an emerging community equity specification, and why I think it’s a very important tool for attracting and developing talent, in addition to growing a body of expert knowledge. People need effective ways to find the right information and mentors so that they can succeed with their BPM projects. And people need tools to develop their careers, especially in industries where new career paths are evolving. Read the rest of this entry »

Posted in User Assistance | 3 Comments »

Source code for Google I/O 2009 examples

May 24th, 2009 Alex Moffat

I’m speaking this week at Google I/O on the topic of Effective GWT: Developing a complex, high-performance app with Google Web Toolkit. The talk includes an example showing how we approach UI development for Lombardi Blueprint which ends up creating the UI below.

The source code for the example is available in this googleio2009.zip file. To execute it

  • Unzip the file.
  • Make sure java is in your path (1.5 or 1.6 will work).
  • Set GWT_HOME to the location of a GWT 1.6.4 install.
  • Run either HostedMode.sh (on OS X) or HostedMode.cmd (on windows).

After a short wait you’ll see a browser window showing the four available stages of the example, each of which builds on the previous one. Click on a link to view the example, you’ll need to wait while hosted mode compiles the Java code but that’s pretty quick.

Posted in EffectiveGWT, GWT | 6 Comments »

Failed CSS Experiments

May 17th, 2009 Alex Moffat

I’v recently been looking at the CSS guidelines from the Yahoo Best Practices for Speeding Up Your Web Site document. What we do for Blueprint is use a number of separate CSS files during development linked together via @import statements. As part of the build process a single CSS file is created for each page by combining the individual files and running the result through the CSS compressor that is part of the YUI Compressor. The name for the combined file is formed using a hash of its contents. This means that whenever the contents changes the file name also changes so we can tell the browser to keep the file permanently cached and still be sure we pick up any style changes.

Just recently I’ve been experimenting with data:url to inline background images into the CSS file. This reduces the number of files the browser has to download, especially in the empty cache situation, and provides caching benefits. After the compression step the build process looks at the CSS and replaces any references to images with a inline data:url, if the size of the image is less than 2k. This works fine for browsers apart from, of course, IE7 and below, which don’t support data:url.
Read the rest of this entry »

Posted in CSS | 2 Comments »

Code Coverage for CSS – Part Two

May 4th, 2009 Alex Moffat

I’ve been busy recently with my Google I/O presentation so I’ve not had the time to do much work on CSS coverage. However, there is some progress to report. One of the comments to my previous post pointed to Dust-Me Selectors, another Firefox plugin that collects and displays CSS usage information. I’ve modified the CSS Coverage plugin to use the technique Dust-Me Selectors uses to collect all of the rules defined in all of the stylesheets referenced by a page. At least I think it’s the same technique, I’ve not actually looked at the code.
Read the rest of this entry »

Posted in CSS | 3 Comments »