Total Pageviews

Wednesday 14 August 2013

Configuring Tomcat for gzip compression

Before going in details of configuring Tomcat for gzip compression, let us have a brief over gzip compression:

When a user hits a url in the browser, a http call is made to the server for the requested page or file. The bigger the size of requested content the longer it would take to get to the browser. This cost not only in terms of time a user spent while waiting for the response but in terms of network bandwidth as well.

Here, gzip compression could be used. The requested webpages/style sheets/java scripts/ image files etc. could be compressed before sending them over to the browser, which exceptionally reduces transfer time as the files are much smaller now.

It begins from the application server which either returns a compressed resource if it supports the zip compression else an unzipped resource.

Gzip locates similar strings within the files and replaces those strings temporarily to make the overall file size smaller. Usually CSS files, java script files and HTML files use a lot of repeated text and have loads of whitespace, which could be highly compressed using gzip and can reduce load time of files drastically.

The exchange of compressed content between browser and server could be verified through exchange of headers between them:
1. The browser sends a header telling the server that it accepts compressed content (gzip / deflate are two compression schemes): Accept-Encoding: gzip, deflate
2. The server sends a response if the content is actually compressed: Content-Encoding: gzip

If the server doesn't send the content-encoding response header, it means the file is not compressed. The "Accept-encoding" header is just a request by the browser, not a constraint for the server. If the server doesn't returns the compressed content, the browser has to render the heavy response.

Configuring Tomcat for gzip compression:
For configuring the tomcat for gzip, it is only required to update the ‘connector’ element inside /conf/server.xml for the following attributes as:

compression="on"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html, text/xml, text/css, application/xml, application/xhtml+xml, application/rss+xml, application/javascript, application/x-javascript"


The explanation for the used connector attributes is as follows:

1. compression: The Connector may use HTTP/1.1 GZIP compression in an attempt to save server bandwidth. The acceptable values for the parameter is "off" (disable compression), "on" (allow compression), "force" (forces compression in all cases), or a numerical integer value (which is equivalent to "on", but specifies the minimum amount of data before the output is compressed). If not specified, this attribute is set to "off" by default.

2. noCompressionUserAgents: The value is a comma separated list of regular expressions matching user-agents of HTTP clients for which compression should not be used, because these clients, although they do advertise support for the feature, have a broken implementation. The default value is an empty String (regexp matching disabled).

3. compressableMimeType: The value is a comma separated list of MIME types for which HTTP compression may be used. The default value is text/html,text/xml,text/plain if nothing is specified.

Steps to verify the compression:
1. Update the configuration as said above and restart the server.
2. Check if the you are getting ‘Content-Encoding: gzip’ header in HttpResponse.( could be checked though firebug add-on available for Mozilla firefox).

Following are some screenshots taken from firebug showing the difference in load time and in response size with and without gzip compression:

1. Without gzip compression: Size: 628.7 Kb, Load Time: 1.07 seconds

2. With gzip Compression: Size: 187.5 Kb, Load Time: 925 milliseconds