Porotype Notes from a Vaadineer

Compressing all the Vaadin things

It’s usually a good idea to gzip compress all the plaintext http traffic in @Vaadin for speed and in order to minimize the amount of transferred data. This is another server-specific configuration, and is again applicable generally and not just for Vaadin.

UPDATE: Click on images for hi-res in new window.

What?

When gzip compression is enabled, the server will compress the data sent to the browser, often resulting in quite dramatic reduction of the size of the transferred data thus download time. Compression is used for plain-text content, which can typically be compressed quite efficiently (achieved compression ratio vs. increase in CPU load) with the gzip algorithm. If you don’t have a very specific reason not to do so, it’s usually a good idea to let the server  handle this (as opposed to rolling your own implementation), since it will be optimized for this use-case.

The decision whether to compress is actually depends on a number of things: first the browser tells the server whether or not it supports compression using the Accept-Encoding http header, and if the server also has compression support turned on it will check the mime-type of the content, and potentially the length, before deciding whether or not to compress. If the content is compressed, the server will add a Content-Encoding http header to inform the browser of this fact. You can get more details about this form Wikipedia.

When?

We obviously don’t want to (try to) compress stuff that is already very well compressed, such as jpeg files, so the server needs to know which mime-types we want to compress. Usually the server comes preconfigured to compress some well-known types, such as HTML and CSS, but one mime-type that is usually missing is the one used for the JSON communication that Vaadin uses - namely application/json

Servers also usually support configuring a minimum content-length for compression, since compression does not work very well for very short content. In the Vaadin JSON case however, the content-length is not known at the time the headers are sent, so it’s all or nothing - the minimum content length can not be checked. This is not usually a problem, though - Google recommends a limit between 150-1000 bytes, which is easily exceeded by most Vaadin JSON messages. If you have lots of very small messages (maybe some sort of polling/push) you might want to check this though.

How?

This is again a server specific configuration issue; please also read your server’s documentation for details. The general method is to make sure compression is enabled (it usually is), and that it’s enabled for all the appropriate mime-types (something might be missing). We’ll take a quick look at the usual suspects, Tomcat and Jetty.

Tomcat

In Tomcat, you should configure your connector to have compression=“on” and compressableMimeType set to the appropriate mime-types (the default in Tomcat 7 is “text/html,text/xml,text/plain”, which indeed is missing application/json). Additionally, you can tune the compressionMinSize to match Googles recommendations. You can do this in the server.xml:

<Connector port="8080"
   …OTHER STUFF...
   compression="on"
   compressionMinSize="500"
   compressableMimeType="text/html,text/xml,text/plain,application/javascript,application/json"/>

The documentation can be found here: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

Jetty

In Jetty, you have to enable and configure the GzipFilter for your application. You can do this by adding a filter definition to your web.xml:


<filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
    <init-param>
      <param-name>mimeTypes</param-name>
      <param-value>text/html,text/xml,text/plain,application/javascript,application/json</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Note that you could actually apply the filter to just Vaadin JSON requests (*/UIDL), but then no other content would be compressed.

Also, with Jetty you can pre-compress static files (index.html -> index.html.gz) and easily have Jetty serve those instead. Refer to the documentation for details: http://docs.codehaus.org/display/JETTY/GZIP+Compression

Testing

Ok, so now you know in theory how to enable gzip compression for Vaadin in Tomcat and Jetty. But in practice you’ll want to make sure that all the appropriate mime-types are compressed, and verify that it’s actually working and making a difference. You can use the Development Tools in Chrome, or Firebug in Firefox to do that - let’s take a look:

Here is how a compressed response looks (in Chrome):

And here is a response without compression (in Chrome):

Here is the same request, compressed and uncompressed (in Firefox):

I suggest you try it out to learn how to spot the difference: fire up a project in Eclipse, and have a look in Chrome/Firebug - chances are you don’t have any compression enabled. Then try modifying server.xml and see how it affects the responses.

As always, feedback is welcome! Errors, comments, more details needed - let me know!