在缓存时间内,浏览器将不会重新访问服务端获取资源。
Http1.0的控制方法是一个过期日期,设置当前时间加上一个过期时间,用response.setDataHeader()可以1900年来豪秒为参数,会转换为Http协议的时间格式输出。
Http1.1的控制方法简单点,直接输出过期时间即可,以秒为单位。
如果要设置无缓存,可设置如下:
//Http 1.0 header
response.setDateHeader("Expires", 0);
//Http 1.1 header
response.setHeader("Cache-Control", "no-cache");
WebUtils中提供了这两个函数,如果在Servlet代码中可以自行使用。但如果是静态内容,因为在Tomcat里貌似没有配置的地方,所以要使用ResponseHeaderFilter来拦截配置,见showcase的web.xml, 其中31536000是一年的秒数。
<filter> <filter-name>expiresHeaderFilter</filter-name> <filter-class>org.springside.modules.web.ResponseHeaderFilter</filter-class> <init-param> <param-name>Cache-Control</param-name> <param-value>public, max-age=31536000</param-value> </init-param> </filter> <filter-mapping> <filter-name>expiresHeaderFilter</filter-name> <url-pattern>/img/*</url-pattern> </filter-mapping>
如果没有设置缓存头,IE会认为没有缓存,而FireFox会看有没有设置LastModify头,如果有设置,缓存时间为 (当前时间-lastModify)/10.
1.2 Last-Modified与Etag
但无缓存或缓存过期后,浏览器再次向服务端发起内容请求时,会附带Last-Modified或Etag header, 如果服务端发现没有更改则直接返回304,无需再传输一遍内容。
Last-Modified是一个日期,同样使用response.setDataHeader()输出。而Http1.1 ETag则是一个自定义字符串,使得可以更灵活的业务意义来进行控制,但缺点是必须由Etag的发出者才能解释字符串的意义。
WebUtils中提供了设置两种Header 与判断两种Header是否已修改的函数。
1.3 压缩传输
对于大量的文本文件,使用Gzip压缩传输能大大缩减传输内容,如dojo.js 从78k压到了28k。 但压缩只对文本有效,对二进制数据几乎没什么作用,对太小的文本也没什么必要。
可以简单配置tomcat的server.xml,同时规定只压缩文本类型,且规定gzip文件的最小大小,
<Connector port="8080" protocol="HTTP/1.1" redirectPort="8443" compression="on" compressionMinSize="2048" compressableMimeType="text/html,application/xhtml+xml,text/xml,text/css,text/javascript" />
也可以参考showcase的StaticContentServlet在代码中进行处理,注意如果要设置content-length,必须要设置压缩后的大小,否则就不要设置content-length,用http 1.1的trunked encoding传输好了。1
2. YUICompressor
CSS/JavaScript们经过紧凑编码后可以省下很大很多的内容。YUICompressor自称比Dojo的压缩工具和JSMIN都要好的一点。
参考showcase中的bin/yuicompressor.bat, 压缩命令如下
java -jar ../lib/yuicompressor-2.3.6.jar -o ../webapp/css/yui.css ../webapp/css/yui-src.css