关于静态资源压缩技术

  HTTP 压缩能够大大提升浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对 于普通的浏览过程HTML ,CSS,Javascript , Text ,它能够节省40%左右的流量。更为重要的是,它能够对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。
目前实现gzip压缩有2种办法:


方法1、是有的容器(服务器)提供的功能,但这个局限于特定容器。好比 apache+tomcat 或者 resin-pro
方法2、是 部署前手动 gzip 压缩,配合 servlet 过滤器使用,这个能实现 gzip 功能,可是下降了灵活性。


方案一
一、TOMCAT配置GZIP压缩:

tomcat5.5.x配置
修改%TOMCAT_HOME%\conf \server.xml启用支持gzip压缩.
添加下列属性
compression="on"
compressionMinSize="2048"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml"
TOMCAT配置说明
1) compression="on" 打开压缩功能
2) compressionMinSize="2048" 启用压缩的输出内容大小,这里面默认为2KB
3) noCompressionUserAgents="gozilla, traviata" 对于如下的浏览器,不启用压缩
4) compressableMimeType="text/html,text/xml" 压缩类型

Resin容器中配置GZIP压缩方法

http://localhost:8080/MyProj/pdf/0.jpg 能够打开一张图片。用Httpwatch查看
Accept-Encoding: gzip, deflate
Sent    :    315
Received    43106

开始配置Resin

我按照这样的配置:
<web-app id="/" root-directory="webapps/MyProj">
<filter filter-name="gzip" filter-class="com.caucho.filters.GzipFilter">
<init>
<use-vary>true</use-vary>
</init>
</filter>
<filter-mapping filter-name="gzip">
<url-pattern>
<exclude-pattern>*.jpg</exclude-pattern>
<include-pattern>/*</include-pattern>
</url-pattern>
</filter-mapping>
</web-app>

再测试发现不起做用!不清楚如何配置哦!
我再看了一下资料上面有讲说 须要resin的专业版即resin-pro
如今再看下个人resin :Resin-3.2.1 (built Fri, 17 Oct 2008 04:11:01 PDT)

果真是个人版本不一致致使的。从新从网上下载一下专业版的RESIN下来再试!
如下是我再测试的过程:
测试发现仍是不行呀!我昏~~~ 不过感受专业版与普通版在配置上面仍是有点差异的
待续未完!

方案二:
设置Content-Encoding

Content-Encoding 文档的编码(Encode)方法。只有在解码以后才能够获得Content-Type头指定的内容类型。利用gzip压缩文档可以显著地减小HTML文档 的下载时间。Java的GZIPOutputStream能够很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 四、IE 5才支持它。所以,Servlet应该经过查看Accept-Encoding头(即request.getHeader("Accept- Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其余浏览器返回普通页面。
压缩流
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
OutputStream out = null;
String encoding = request.getHeader("Accept-Encoding");  
if (encoding != null && encoding.indexOf("gzip") != -1){
request.setHeader("Content-Encoding" , "gzip");  
out = new GZIPOutputStream(request.getOutputStream());
} 
else if (encoding != null && encoding.indexOf("comdivss") != -1){
request.setHeader("Content-Encoding" , "comdivss");  
out = new ZIPOutputStream(request.getOutputStream());
}else{  
out = request.getOutputStream();



实例:
采用gzip servlet filter实现
从 HTTP/1.1 开始,客户端就能够在请求头中添加
Accept-Encoding: gzip,deflate      (能够从HTTP WATCH中查看发现确实支持)
来向请求的服务器代表本身支持 Gzip 压缩的响应。Web 服务器则在响应头中添加
Content-Encoding: gzip
来向客户端代表响应体是通过 gzip 压缩的。

程序代码以下:
(在此很是感谢 http://tdcq.iteye.com/blog/453644 提供代码)

具体代码以下:
package sh.blog.util.web.filter;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
public class CompressedStream extends ServletOutputStream {
private ServletOutputStream out;
private GZIPOutputStream     gzip;
/**
* 指定压缩缓冲流
* @param 输出流到压缩
* @throws IOException if an error occurs with the {@link GZIPOutputStream}.
*/
public CompressedStream(ServletOutputStream out) throws IOException {
this.out = out;
reset();
}

/** @see ServletOutputStream * */
public void close() throws IOException {
gzip.close();
}

/** @see ServletOutputStream * */
public void flush() throws IOException {
gzip.flush();
}

/** @see ServletOutputStream * */
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}

/** @see ServletOutputStream * */
public void write(byte[] b, int off, int len) throws IOException {
gzip.write(b, off, len);
}

/** @see ServletOutputStream * */
public void write(int b) throws IOException {
gzip.write(b);
}      

public void reset() throws IOException {
gzip = new GZIPOutputStream(out);
}

}



package sh.blog.util.web.filter;
import java.io.IOException;
import java.io.PrintWriter;   
import javax.servlet.ServletOutputStream;   
import javax.servlet.http.HttpServletResponse;   
import javax.servlet.http.HttpServletResponseWrapper;     

public class CompressionResponse extends HttpServletResponseWrapper{
protected HttpServletResponse response;   
private ServletOutputStream out;   
private CompressedStream compressedOut;  
private PrintWriter writer;   
protected int contentLength;   

public CompressionResponse(HttpServletResponse response) throws IOException {   
super(response);
this.response = response;   
compressedOut = new CompressedStream(response.getOutputStream());
}

public void setContentLength(int len) {
contentLength = len;   
}

public ServletOutputStream getOutputStream() throws IOException {   
if (null == out) {   
if (null != writer) {  
throw new IllegalStateException("getWriter() has already been called on this response.");   
}
out = compressedOut;   
}
return out;
}

public PrintWriter getWriter() throws IOException {   
if (null == writer) {   
if (null != out) {   
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
writer = new PrintWriter(compressedOut);  
}
return writer;   

}

public void flushBuffer() {   
try {   
if (writer != null) {
writer.flush();
}else if (out != null) {  
out.flush();   
}

}catch (IOException e) {  
e.printStackTrace();   
}
}

public void reset() {
super.reset();   
try {   
compressedOut.reset();   
}catch (IOException e) {  
throw new RuntimeException(e);   
}
}

public void resetBuffer() {   
super.resetBuffer();   
try {   
compressedOut.reset();   
}catch (IOException e) {  
throw new RuntimeException(e);
}
}

public void close() throws IOException {   
compressedOut.close();   
}



}



package sh.blog.util.web.filter;

import java.io.IOException;   
import java.util.Enumeration;   
import javax.servlet.Filter;   
import javax.servlet.FilterChain;   
import javax.servlet.FilterConfig;   
import javax.servlet.ServletException;   
import javax.servlet.ServletRequest;   
import javax.servlet.ServletResponse;   
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletResponse;   
import org.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   

public class CompressionFilter implements Filter {   
protected Log log = LogFactory.getFactory().getInstance(this.getClass().getName());   

@SuppressWarnings("unchecked")   
public void doFilter(ServletRequest request, ServletResponse response,   
FilterChain chain) throws IOException, ServletException {   
boolean compress = false;   
if (request instanceof HttpServletRequest){   
HttpServletRequest httpRequest = (HttpServletRequest) request;  
Enumeration headers = httpRequest.getHeaders("Accept-Encoding");   
while (headers.hasMoreElements()){   
String value = (String) headers.nextElement();   
if (value.indexOf("gzip") != -1){   
compress = true;   
}   
}   
}   

if (compress){//若是浏览器支持则压缩   
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.addHeader("Content-Encoding", "gzip");   
CompressionResponse compressionResponse= new CompressionResponse(httpResponse);   
chain.doFilter(request, compressionResponse);   
compressionResponse.close();   
}   
else{//若是浏览器不支持则不压缩   
chain.doFilter(request, response);   
}   

}   

public void init(FilterConfig config) throws ServletException {   

}   

public void destroy(){   
}   

}   
一共有三个CLASS文件!实现GZIP压缩输出响应

2.1 对图片输出作压缩处理测试
创建目录pdf里面存储图片
第一步:不配置过滤器用HTTP WATCHE发现
image/jpeg : 42891 bytes, 670 x 446 pixels


第二步:配置Web.xml配置过滤器
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/pdf/*</url-pattern>
</filter-mapping>

再用HTTP WATCH查看发现
image/jpeg : 42891 bytes, gzip compressed to 42712 bytes ( 0.417 % saving ), 670 x 446 pixels
实现了一次压缩处理输出!
PS:我再用png格式的图片作过一次测试发现一次能够实现GZIP压缩输出
结论:经过上面的过滤器可以实现对图片的压缩处理,提升响应速度!


2.2 对音乐的压缩处理以MP3的输出 为测试对象

创建目录music里面存储音乐
第一步:不配置过滤器发现
audio/mpeg : 9001 bytes of binary data

第二步:配置过滤器

<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/music/*</url-pattern>   
</filter-mapping>

再次查看发现:
audio/mpeg : , gzip compressed to 0 bytes ( 0 % saving )
结论:上面的算法对音乐文件不起压缩做用。感受这种GZIP的算法应该是不一样的格式算法不同


2.3 对JS文件压缩输出

第一步:不作压缩
4864

第二步:配置压缩
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>   
</filter-mapping>

输出:
application/x-javascript : 4636 bytes, gzip compressed to 69 bytes ( 98.5 % saving )

查看发现JS的压缩是至关高的了!
结论:将JS存入指定的目录而后直接对此目录作GZIP压缩输出。能够看到效果是显著的!
经过作GZIP压缩输出以后能够减小网络带宽流量从而加快下载速度!



2.4 对CSS文件压缩输出

第一步:没有压缩输出
text/css : 413 bytes

第二步:压缩

配置:
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>   
<url-pattern>/style/*.css</url-pattern>
</filter-mapping>
结果:
text/css : 413 bytes, gzip compressed to 101 bytes ( 75.5 % saving )
结论:对CSS的压缩效果也是很是明显的哦!

2.5 对HTML页面压缩输出

第一步:不压缩
text/html : 2272 bytes

第二步;压缩
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>   
<url-pattern>/style/*.css</url-pattern>
<url-pattern>*.html</url-pattern>
</filter-mapping>
结果:
text/html : 2272 bytes, gzip compressed to 240 bytes ( 89.4 % saving )

结论:对HTML的压缩效果也是很是明显的哦!

2.6 对JSP页面的压缩
第一步:未作压缩
text/html; charset=iso-8859-1 : 1008 bytes

第二步:压缩输出
<filter>
<filter-name>gzip</filter-name>
<filter-class>sh.blog.util.web.filter.CompressionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/scripts/*.js</url-pattern>   
<url-pattern>/style/*.css</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>

结果:页面 无输出!

结论:
以上的算法能够应用于 图片、HTML、CSS、JS的GZIP压缩输出。对于JSP页面无效!

应用:

未来能够在站点中编写此类过滤器,将页面内容尽量地作GZIP输出提升下载的速度 javascript




这是我在别处看到帖子 比较不错  但愿你们能够看下
css

相关文章
相关标签/搜索