最近在做前端的性能优化,发现一个页面引入的js、css等外部资源过多的话,浏览器第一次请求的时候会下载很大的资源,那么在用户网络不好的情况下,页面的加载速度会受很大的影响,因此要对WEB前端做各种优化。
在此第一步做的就是所有资源的压缩,在开发环境编写好的js和css文件,可以使用工具批量压缩成min的文件格式,那样会压缩一部分大小,但是js压缩成min.js要注意有些方法可能不好使,这方面大家可以百度一下资料。
其次可以做本文所说的gzip压缩,这种压缩比率可以让传输资源文件的大小缩小为40%左右,也就是压缩了60%多,这种效果也是很明显的。
但是在调查过程中发现,网上全部都是基于tomcat或者ngix的配置文件的修改,我一直没有找到基于resin4的配置修改方式,因为就只能在代码上下功夫了。
原理就是做filter过滤,把返回给浏览器的数据全部做gzip压缩,到时候浏览器会自动解压的。代码里的gzip压缩其实就是java类中的一种压缩方式而已,下面就上所用到的代码。
web.xml文件,增加一个filter
工程里面需要三个类
GzioFilter.java
import java.io.IOException;
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;
public class GzioFilter implements Filter{
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest)req;
HttpServletResponse response =(HttpServletResponse)res;
String acceptEncoding = request.getHeader("Accept-Encoding");
if (acceptEncoding != null
&& acceptEncoding.toLowerCase().indexOf("gzip") != -1) {
GZipResponseWrapper gzipResponse = new GZipResponseWrapper(response);
chain.doFilter(request, gzipResponse);
gzipResponse.finishResponse();
}else{
chain.doFilter(request, response);
}
}
public void init(FilterConfig arg0) throws ServletException {
}
}
GZipOutputStream.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
public class GZipOutputStream extends ServletOutputStream {
private HttpServletResponse response;
private GZIPOutputStream gzipOutputStream;
private ByteArrayOutputStream byteArrayOutputStream;
public GZipOutputStream(HttpServletResponse response) throws IOException {
this.response = response;
byteArrayOutputStream = new ByteArrayOutputStream();
gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
}
public void write(int b) throws IOException {
gzipOutputStream.write(b);
}
public void close() throws IOException {
gzipOutputStream.finish();
byte[] content = byteArrayOutputStream.toByteArray();
response.addHeader("Content-Encoding", "gzip");
response.addHeader("Content-Length", Integer.toString(content.length));
ServletOutputStream out = response.getOutputStream();
out.write(content);
out.close();
}
public void flush() throws IOException {
gzipOutputStream.flush();
}
public void write(byte[] b, int off, int len) throws IOException {
gzipOutputStream.write(b, off, len);
}
public void write(byte[] b) throws IOException {
gzipOutputStream.write(b);
}
}
GZipResponseWrapper.java
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class GZipResponseWrapper extends HttpServletResponseWrapper {
private HttpServletResponse response;
private GZipOutputStream gzipOutputStream;
private PrintWriter writer;
public GZipResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
this.response = response;
}
public ServletOutputStream getOutputStream() throws IOException {
if (gzipOutputStream == null)
gzipOutputStream = new GZipOutputStream(response);
return gzipOutputStream;
}
public PrintWriter getWriter() throws IOException {
if (writer == null)
writer = new PrintWriter(new OutputStreamWriter(
new GZipOutputStream(response), "UTF-8"));
return writer;
}
public void setContentLength(int contentLength) {
}
public void flushBuffer() throws IOException {
gzipOutputStream.flush();
}
public void finishResponse() throws IOException {
if (gzipOutputStream != null)
gzipOutputStream.close();
if (writer != null)
writer.close();
}
}
原理很简单,做web开发的同学应该都可以看懂。