Skip to main content

JSF StateSaving and Compression

Posted by jhook on December 7, 2006 at 11:25 PM PST

StateSaving in JSF is the uncle no one wants to talk about. You get a lot of things for 'free' with JSF, but for the most part, these features end up adversely affecting the state size of the view.

JSF has two options for StateSaving: client and server (actually pluggable for anything you want). The basic rule of thumb is if you want to save memory, you go with client state saving-- pushing Object state to the client, encoded in the view. StateSaving server is a bit more performant, but retains stacks of views in the user's HttpSession.

What I want to focus on is client StateSaving. With saving state on the client, you are basically serializing an object graph and outputting it into the page as a Base64 String. Optional features here include encryption and compression. Encryption is only needed in rare cases-- but compression is often enabled. From my own tests, compressing JSF state means a reduction in size by at least a factor of 10 (hmmm... maybe this tells us something ;-).

By default, client state is compressed with normal GZip. I believe MyFaces actually opts out of compression by default, but any of Jason Hunter's old articles on Compression Filters actually tell you that compression is a good thing with network latency. Yes, compression adds processor overhead, but lets see if we can't look at some alternatives to GZip?

Diving through java.util.zip, I know that there are other 'Deflaters' available which have interesting 'types'-- such as Best Performance, Huffman, Best Compression, etc. Let's see how these compare with a grossly large JSF page (basically 100 pages put together in one) and averaged over hundreds of iterations of StateSaving:

Update: I've added Ryan's JMeter results from trying some of these algorithms against the CarDemo app with 50 threads running for 5 minutes at random intervals of 200-300ms.

Algorithm/Type Size in Bytes Write in Milliseconds Read in Milliseconds Total in Milliseconds Request/Second Bytes/Second # of Hits
None (Default MyFaces) 174,345 78.14 198.12 276.26 91.8 2,529.89 27,598
GZip (Default RI) 12,864 103.72 205.68 309.4 58.6 518.05 17,633
Default Compress 12,852 93.42 174.08 267.50 - - -
Best Compress 11,855 110.24 171.04 281.28 62.2 544.76 18,695
Best Speed 16,480 86.58 176.24 262.82 63.5 569.02 19,091
Huffman 15,190 79.46 175.22 254.68 63.8 590.21 19,181
Filtered 16,480 79.36 176.88 256.24 64.1 600.97 19,272

The different algorithms are listed within the java.util.zip package in the javadocs, but I found the numbers to be pretty interesting. Of course, I'm a compression n00b, so if anyone had any comments on why it would be bad to switch to one of the other algorithms as a set-able option with JSF, please let me know!

I should note too that smaller page sizes, all the algorithms fluxate in timings between runs by quite a bit (5ms > 0ms) which may be attributed purely to GC or the ObjectOutput/InputStream itself.

Related Topics >>