Javascript开发之js压缩篇

Extjs可以说是目前最优秀的js开发库了。除了那个蹩脚的GPLV3授权。
但是使用中遇到的第一个问题就是,Extjs那庞大的个头。想办法压缩ExtJS的大小成了首先要解决的问题。
谈谈我的解决方法,欢迎拍砖。突然发现前面那个广告贴被锁了 :(

1、压缩混淆
除了ExtJS的大个子以外,引用的很多其他的js库,项目中自己的js文件等等。采用OPOA组件式开发最后一定会增大js文件的总量。所以项目后期要对这些文件进行压缩合并。现在流行的js压缩工具有很多,如packer,jsMin,Esc,JSA,yui-compressor等等。经过实际使用我选的是yui-compressor.
yui-compressor项目地址:http://developer.yahoo.com/yui/compressor/
下载后得到一个java开发的jar包。使用方法基于命令行:
java -jar yuicompressor-x.y.z.jar [options] [input file]
开发中的js文件不可能一个个的手动压缩,这里用到了ANT。在项目构建中可以替你完成以上任务。

<property name="yuicompressor" value="${tools}/yuicompressor-2.3.6.jar" />
<apply executable="java" parallel="false" verbose="true" dest="${dist}/WebRoot">
<fileset dir="${dist}/WebRoot">
<include name="modules/*.js" />
<include name="js/*.js" />
</fileset>
<arg line="-jar" />
<arg path="${yuicompressor}" />
<arg line="--type js --charset UTF-8 -o" />
<targetfile />
<mapper type="glob" from="*.js" to="*-m.js" />
</apply>
<concat destfile="${dist}/WebRoot/js/base.js" encoding="UTF-8" >
<fileset dir="${dist}/WebRoot/js">
<include name="*-m.js" />
</fileset>
</concat>
<concat destfile="${dist}/WebRoot/modules/modules.js" encoding="UTF-8" >
<fileset dir="${dist}/WebRoot/modules">
<include name="*-m.js" />
</fileset>
</concat>
<delete>
<fileset dir="${dist}/WebRoot">
<include name="js/*.js"/>
<include name="modules/*.js"/>
<exclude name="modules/modules.js" />
<exclude name="js/base.js" />
</fileset>
</delete>



2、gzip压缩。
坛子里讨论的gzip压缩有2种,
一是有的容器(服务器)提供的功能,但这个局限于特定容器。比如apache+tomcat或者resin-pro版。
二是部署前手动gzip压缩,配合servlet过滤器使用,这个能实现gzip功能,但是降低了灵活性。
我自己用的是自己的实现,采用gzip servlet filter实现。下面是我的代码参考网上内容.


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);
}

/**
* Resets the stream.
*
* @throws IOException if an I/O error occurs.
*/
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;

/**
* 创建一个新的被压缩响应给HTTP
*
* @param response the HTTP response to wrap.
* @throws IOException if an I/O error occurs.
*/
public CompressionResponse(HttpServletResponse response) throws IOException {
super(response);
this.response = response;
compressedOut = new CompressedStream(response.getOutputStream());
}

/**
* Ignore attempts to set the content length since the actual content length
* will be determined by the GZIP compression.
*
* @param len the content length
*/
public void setContentLength(int len) {
contentLength = len;
}

/** @see HttpServletResponse * */
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;
}

/** @see HttpServletResponse * */
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;
}

/** @see HttpServletResponse * */
public void flushBuffer() {
try {
if (writer != null) {
writer.flush();
} else if (out != null) {
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}

/** @see HttpServletResponse * */
public void reset() {
super.reset();
try {
compressedOut.reset();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

/** @see HttpServletResponse * */
public void resetBuffer() {
super.resetBuffer();
try {
compressedOut.reset();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

/**
* Finishes writing the compressed data to the output stream. Note: this
* closes the underlying output stream.
*
* @throws IOException if an I/O error occurs.
*/
public void close() throws IOException {
compressedOut.close();
}
}


/**
* 如果浏览器支持解压缩,则压缩该代码
* @throws IOException ServletException if an error occurs with the {@link GZIPOutputStream}.
* 如果需要开启该过滤器,在web.xml中加入此代码
<filter>
<filter-name>gzip</filter-name>
<filter-class>com.strongit.finance.gzip</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
*/

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(){

}
}


实际使用的效果以[url]http://demo.slivercrm.cn:8084[/url]为例

登陆窗口:

[img]/upload/attachment/90419/1e5b41ff-a837-3ee0-9f99-5513132b3433.png[/img]

[img]/upload/attachment/90421/71e5dd32-f114-3ebb-8e29-bea0ad38ef19.png[/img]

首页:

[img]/upload/attachment/90423/8c69f0b3-d48c-3458-a98d-4e68efbaa0c0.png[/img]

[img]/upload/attachment/90425/f434b33b-28cd-344c-b2bb-14235d9b1dd9.png[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值