Browser caching of Vaadin Widgetset

Hi all,

I’m trying to improve the performance of my Vaadin app by using browser caching to prevent additional requests for my widgetset each time the user loads the window. However I’m struggling with this, and was wondering if any one can offer some advice.

My setup:

  • Tomcat 7.0.23
  • VAADIN/* requests are served by DefaultServlet as I have extracted theme and widgetset info into /VAADIN in my webapp
  • requests are made over SSL, although I cannot see why this should be an issue

  • I’ve been predominately testing this with Chrome, but I’m seeing the same behaviour in other browsers
  • I’m only seeing this in Chrome. I double checked and Firefox is correctly serving the resource from the browser cache.

My Tomcat Connectors are configured as follows:


<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"  maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="${user.home}/.keystore" keystorePass="${keyStorePass}" compression="on" compressionMinSize="350" compressableMimeType="text/html,text/xml,text/plain,text/css" />

This is reducing the size of the widget significantly by using the in-built Tomcat 7 GZip compression.

In addition to this, I am using the Tomcat 7 Expires Filter (http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#Expires_Filter ) to set cache control headers on resources served by DefaultServlet. This is configured as so in web.xml


<filter>
	<filter-name>ExpiresFilter</filter-name>
  	<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
	<init-param>
		<param-name>ExpiresByType text/html</param-name>
		<param-value>access plus 8 hours</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>ExpiresFilter</filter-name>
	<servlet-name>default</servlet-name>
</filter-mapping>

Essentially anything with content-type text/html is OK for the browser to cache for 8 hours.

The problem I’m experiencing is that this doesn’t seem to cause the browser to cache my widgetset. This means that each time I load a Vaadin page, I’m seeing a request for ~350k of HTML. This is by far and away the biggest part of the request cycle for my page. The following demonstrates what I’m seeing:

This shows the network usage, where the widgetset is requested. This happens each time I access the Vaadin app

Inspecting the request and response headers, you can see that the Expires and Cache-Control headers are correctly set. However looking at the request header, there is no “if-modified-since” in the request. I suspect this is the root cause of the problem, but I have no idea how to determine why this is not being sent.

Has anyone else successfully used browser-caching for the Vaadin widgetset as it would offer a significant performance improvement for my application.

I may be able to answer my own question. It would appear that Chrome does not send the if-modified-since headers for HTML resources. See this link:


http://code.google.com/p/chromium/issues/detail?id=41880

There seems to be some debate as to whether it affects all requests, or just Ajax requests. However, If I am right about this, then it would suggest that there is a significant performance penalty when using Vaadin in Chrome in comparison to say Firefox, which seems to correctly cache the widgetset.

It should be noted that this only happens when the user first opens the window, but for those of us who are making use of different application windows, this is certainly an issue.

Try
https://vaadin.com/directory
with chrome. There widgetset caches just fine.

What might be the difference between your configuration and /directory?

Hi Joonas,

Thanks for that. Very interesting. As you say, the widgetset is correctly cached by Chrome we visiting the directory. There are a couple of differences I noticed in the responses:

  • The Directory is using Apache to serve resources, not Tomcat
  • The Directory issues strong Etags, Tomcat issues weak Etags

Looking around, it appears that there may be an issue with weak Etags in certain browsers. Perhaps this is the problem. I can try and make Tomcat issue strong Etags for resources served by DefaultServlet to see if that makes any difference.

cheers,

Rob

As the issue is not Vaadin - or even GWT - specific, it would be quite strange if Chrome could not cache resources from Tomcat.