• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Compression

 
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've been googling all day and don't know whether any of the information I've found is right or wrong, etc.

I'd like to improve my website by providing compressed responses to any browser that supports them. I'm on Tomcat 7 and assuming at the moment that I'm trying to use gzip. Do I still need to write filters and such and configure those here and there, and if so, do you know of a full set of instructions that you believe are correct?

The html page includes css and javascript (in the page itself, not in external files), as well as images. I've reduced image sizes as much as reasonable and use png a lot because webpagetest.org seems to like that. Haven't quite figured out sprites yet ... maybe later.

I'm also pushing "text/xml" and "text/html" out of servlets. I think the output of each of these should be compressed.

I have modified the non-secure (http, not https) Connector in server.xml



 
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Compression in Tomcat is a negotiated facility. Tomcat and the client (browser) have to both agree on compression or it will not be used. You might want to read this:

http://en.wikipedia.org/wiki/HTTP_compression

You do not have to do any additional configuration or modification of Tomcat to get it to use compression. The Connector options are all that are required. Clients normally also have the compression built-in and automatically available.

The stuff that benefits the most from compression are largish text files and certain binaries such as raw database or data file records (even though that's not something a web session generally transfers). So HTML, XML, JavaScript and CSS are all good candidates. JSON may or may not be, depending on how much data is involved. Most images are already compressed, so telling Tomcat to compress them would not only be pointless extra overhead, but might even result in a compressed data stream that is larger than the pre-compression data.

Some additional performance hints. Even better than compression is caching. Cache anything that you safely can, although make sure that stale cache data doesn't cause problems of its own. Few people are aware that Tomcat suppresses caching when in SSL/TLS mode (i.e., https), though. There are security reasons for this, although this suppression can be overridden for stuff that you know is "safe".

And finally, don't under-estimate the benefits of batching. One single (compressed!) javascript file transmits far more efficiently than 20 5-line javascript files. Not only is the network overhead less, but the compression algorithms need a certain minimal amount of data just to come up to proper compression efficiency.
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sounds about right to me. I've gotten feedback from google analytics and webpagetest.org to get me started and your list seems like the one I'm working with. Noticed right off that in last minute changes to "big buttons" (images for major links) hadn't been minimized in size, and converted them to png as well, which webpagetest.org found acceptable. I already knew that images are in compressed format (bitmap to jpeg and png ...) but even tried further compression (2% improvement). I'll try to look into sprites at some point too, sending all the big buttons at once. I have both text/xml and text/html coming out of servlets which I believe would shrink up quite a bit. The xml ships product data to the page and there's a bunch of it initially. The html stuff is pretty fast already, efficient by design, but I don't think it will hurt to test it once I have compression working. I'm kind of extreme on batching .. putting both the css and javascript in the head of the html file ... not in external files. Then it says somewhere that maybe much of the javascript should be at the bottom, letting css load first, then html, then javascript. The "home page" is the biggest. I'm wondering if I can ship the whole thing compressed in one batch.

I've looked through the Wikipedia page before and am already quite familiar with handshakes etc. (built my own websocket server, which is an http "upgrade" from scratch). What I need is a roadmap specific to Tomcat. The config I've done so far has had no effect, and I haven't run across any tips on handling my servlet output other than using a gziping object within the application. Looks like you can understand why I'm not sure whether that's right.
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One of the poorest-performing web pages I ever ran across was one of the simplest. It was about 6 buttons on a blank page.

However, the designer had created the button graphics in Visio and saved them as bitmaps. Not realizing that the bitmaps were something like 1600x1200 pixels per button image. The performance hit came when the client-side HTML renderer had to scale them down to the 16x12 pixel images that the actual HTML specified. It was a lot of CPU work for relatively little to show for it.

Batching JavaScript and CSS embedded within a webpage won't help much. The page transmits as a unit and caches as a unit, so no other pages can share the embedded JavaScript and CSS. If the JavaScript and CSS files each have discrete URLs of their own, then caching can work, since the cache key is the URL of the object being cached.

The other reason for not mixing HTML, CSS and JavaScript in the same transmission is that most of the really efficient compression algorithms work by locating frequently-used patterns. When you have 3 different types of content in the same response, the compression algorithms have 3 radically-different frequently-used pattern sets to compact. That causes the overall compression to be less efficient.
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:One of the poorest-performing web pages I ever ran across was one of the simplest. It was about 6 buttons on a blank page.

However, the designer had created the button graphics in Visio and saved them as bitmaps. Not realizing that the bitmaps were something like 1600x1200 pixels per button image. The performance hit came when the client-side HTML renderer had to scale them down to the 16x12 pixel images that the actual HTML specified. It was a lot of CPU work for relatively little to show for it.

Batching JavaScript and CSS embedded within a webpage won't help much. The page transmits as a unit and caches as a unit, so no other pages can share the embedded JavaScript and CSS. If the JavaScript and CSS files each have discrete URLs of their own, then caching can work, since the cache key is the URL of the object being cached.

The other reason for not mixing HTML, CSS and JavaScript in the same transmission is that most of the really efficient compression algorithms work by locating frequently-used patterns. When you have 3 different types of content in the same response, the compression algorithms have 3 radically-different frequently-used pattern sets to compact. That causes the overall compression to be less efficient.



I was starting to think as much. And on caching, I've had to sleep on it overnight. Initially, I was thinking about browser caching, so what I was reading seemed rather other-worldly. (I'm constantly amazed how programmers fail to introduce and orient when they write.) But caching on the server means not needing to read as much from disk ... is that right?
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Tomcat server does not cache.

Depending on what you are using for persistent storage, the persistency system may provide caching services, either built-in and/or via external cache services such as memcached, but Tomcat does not participate in the process.

The only instance where Tomcat gets involved in caching in either the client or server is when it inserts cache-suppression headers into HTTPS output streams for security reasons, so it's more of an un-cache than a cache.
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, then the fog hasn't lifted around me yet. I might need to find one of the things I read to make any question about it clear. You can somehow specify some kind of cache until date and most advice is to set it to max. While I was thinking browser caching, I thought maybe it was telling the browser to keep things that long, but since browsers seem to have minds of their own, I really wasn't sure whether that made sense; unless it's to tell browsers when they need to get new material.
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The site is actually pretty zippy. The big button problem was created during a last minute project crunch when the pressure was on to get the online business started while change requests were piling up. It was just forgotten until I had time to start reviewing performance. Other graphics make the site much nicer, but are a bit heavy for small devices. I'd rather address that with a small device web page.

Where I'd like to focus just now is compressing the product data, which comes from a servlet as xml.
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roger F. Gay wrote:
Where I'd like to focus just now is compressing the product data, which comes from a servlet as xml.



That part's easy. Just ensure that the Content-Type header that you're writing for the XML matches one of the MIME types that you indicated in the Connector. And if it doesn't, add it!
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:

Roger F. Gay wrote:
Where I'd like to focus just now is compressing the product data, which comes from a servlet as xml.



That part's easy. Just ensure that the Content-Type header that you're writing for the XML matches one of the MIME types that you indicated in the Connector. And if it doesn't, add it!



Did that already. All the power of webpagetest.org says it didn't work. Not even getting gzip capability listed in the response header from Tomcat.
IN servlet:
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Time to hit Google, then. There is information out there on that. Plus, remember that https uses a different Connector than http!
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Been to google. As is normally my practice, I went there first. Very few questions make it to the posting stage.
 
Tim Holloway
Saloon Keeper
Posts: 27763
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have better luck, myself. There's a limit to how much work I can do for free, but some of the things I discovered were these:

1. For Tomcat 7, NIO will take precedence over compression, so you should disable it, if that's a problem.
2. Tomcat's compression doesn't apply to Apache/Tomcat connection channels. If you have Apache fronting Tomcat, let Apache handle the compression.
3. You might want to bypass the subtle approach and use compression="force", at least until you have it working

Also, of course, if you are running Tomcat under Eclipse WTP, don't forget that WTP is very bad about not picking up configuration mods until you bash it with a crowbar several times.
 
Roger F. Gay
Ranch Hand
Posts: 409
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
SOLVED: (Tomcat Connector documentation)

Added to connector: useSendfile="false"

Note: There is a tradeoff between using compression (saving your bandwidth) and using the sendfile feature (saving your CPU cycles). If the connector supports the sendfile feature, e.g. the NIO connector, using sendfile will take precedence over compression. The symptoms will be that static files greater that 48 Kb will be sent uncompressed. You can turn off sendfile by setting useSendfile attribute of the connector, as documented below, or change the sendfile usage threshold in the configuration of the DefaultServlet in the default conf/web.xml or in the web.xml of your web application.



Rechecked stats after this started working and it's downright zippy. With a 10th of a second wait for fetching data from a db, page load clocks in at a quarter second when images are already cached. That's the next thing. Devices cache images without my help, but I don't really understand some things that that I've been reading about. If I still have trouble when I try to approach it again, I'll post another question. But, at this point, I'm quite pleased with the improved performance I'm getting from compression.
 
reply
    Bookmark Topic Watch Topic
  • New Topic