1. 程式人生 > >WEB效能優化(一):Resin下的 GZIP壓縮

WEB效能優化(一):Resin下的 GZIP壓縮

最近在做前端的效能優化,發現一個頁面引入的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開發的同學應該都可以看懂。