`
会飞的狗
  • 浏览: 16678 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

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


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

登陆窗口:





首页:




  • 大小: 65.9 KB
  • 大小: 19.4 KB
  • 大小: 23.9 KB
  • 大小: 29.9 KB
分享到:
评论
8 楼 会飞的狗 2010-01-19  
yiminghe 写道
给你提点建议,你自己实现的compress不是很好哦,
1. CompressedStream 没有 buffer ?直接都写入stream不太好
2.wrapper getWriter 没有考虑字符编码问题?,request.getCharacterEncoding可以用用
3.filter 异常处理下

try{
chain.doFilter(request, compressionResponse);
}
finally{ 
            compressionResponse.close(); 
}

恩,已经参考Tomcat examples里面的compressionFilters修改了。
翻了翻servlet api
public interface ServletResponseDefines an object to assist a servlet in sending a response to the client. The servlet container creates a ServletResponse object and passes it as an argument to the servlet's service method.

To send binary data in a MIME body response, use the ServletOutputStream returned by getOutputStream(). To send character data, use the PrintWriter object returned by getWriter(). To mix binary and text data, for example, to create a multipart response, use a ServletOutputStream and manage the character sections manually.

The charset for the MIME body response can be specified explicitly using the setCharacterEncoding(java.lang.String) and setContentType(java.lang.String) methods, or implicitly using the setLocale(java.util.Locale) method. Explicit specifications take precedence over implicit specifications. If no charset is specified, ISO-8859-1 will be used. The setCharacterEncoding, setContentType, or setLocale method must be called before getWriter and before committing the response for the character encoding to be used.

See the Internet RFCs such as RFC 2045 for more information on MIME. Protocols such as SMTP and HTTP define profiles of MIME, and those standards are still evolving.

看下来如果charset未定义,就采用ISO-8859-1  ?
7 楼 yiminghe 2010-01-18  
引用

2.wrapper getWriter 没有考虑字符编码问题?,request.getCharacterEncoding可以用用

sorry , 是 response.getCharacterEncoding 不为null有的话要考虑一下
6 楼 yiminghe 2010-01-18  
给你提点建议,你自己实现的compress不是很好哦,
1. CompressedStream 没有 buffer ?直接都写入stream不太好
2.wrapper getWriter 没有考虑字符编码问题?,request.getCharacterEncoding可以用用
3.filter 异常处理下

try{
chain.doFilter(request, compressionResponse);
}
finally{ 
            compressionResponse.close(); 
}



网上看过已有的实现是比较好的,你可以飕飕
5 楼 jianguang_qq 2009-08-16  
406656983 写道
楼主,上面图片显示压缩后文件大小的工具是什么?

Yslow
4 楼 406656983 2009-08-16  
楼主,上面图片显示压缩后文件大小的工具是什么?
3 楼 会飞的狗 2009-04-11  
占用资源其实不是很大,第一次可能慢一些。第二次就缓存了。
静态压缩你可以搜索本坛badqiu的一篇文章,提供了过滤器实现。
2 楼 TinyJimmy 2009-04-10  
我使用的静态压缩js/css也要设置Content-Encoding, 否则有些浏览器无法判断文件是否已经压缩, 解释出错. 而下发时需要通过Tomcat filter来设置Content-Encoding, 占用资源. 不知道楼主有没有好的方法?
1 楼 pure 2009-04-04  
太强了,学习。。学习

相关推荐

    Javascript开发之js压缩篇.pdf

    "Javascript开发之js压缩篇" 本文主要讲述了使用ExtJS库时遇到的问题,即ExtJS庞大的体积如何进行压缩和优化。文章中介绍了两种解决方法:一、使用yui-compressor对js文件进行压缩混淆,二、使用gzip压缩来减少文件...

    Javascript开发之js压缩篇.docx

    ### JavaScript开发之JS压缩技术详解 #### 一、引言 在JavaScript开发过程中,随着项目的不断扩展和功能的增加,JavaScript文件的数量与体积往往会变得非常庞大。这不仅增加了页面加载的时间,也消耗了大量的网络...

    JavaScript开发工具 共享

    JavaScript开发工具是Web开发中的重要组成部分,它极大地提升了前端开发者的工作效率。JavaScript作为一种动态类型的脚本语言,广泛应用于网页交互、浏览器扩展、服务器端开发(Node.js)等多个领域。随着技术的发展...

    利用JAVASCRIPT即你想那个GZIP压缩与解压缩

    标题中的“利用JAVASCRIPT实现GZIP压缩与解压缩”指的是在JavaScript环境中,我们可以使用原生或第三方库来处理GZIP格式的压缩和解压缩操作。GZIP是一种广泛使用的数据压缩格式,常用于减少网络传输的数据量,尤其是...

    javascript混淆,javascript压缩,javascript加密软件

    "javascript混淆"、"javascript压缩"和"javascript加密"就是针对这一需求的三个关键概念。 **JavaScript混淆**: 混淆JavaScript代码的主要目的是为了增加攻击者逆向工程的难度,防止代码被轻易理解和篡改。混淆...

    java开发中压缩js,css文件

    在Java开发中,压缩JavaScript(js)和CSS(样式表)文件是一项常见的优化技术,用于减少网页加载时间和提高用户体验。这种技术通常被称为“文件合并与压缩”,它将多个js和css文件合并为一个文件,并去除其中不必要...

    jsmin js 压缩工具 javascript 压缩工具

    "jsmin"是一个高效的JavaScript压缩工具,其主要目的是通过删除不必要的字符(如空格、注释和换行)以及缩短变量名来减小JS文件的大小,从而提高页面加载速度。这个工具的设计理念是尽可能地保留原始代码的功能,...

    Javascript压缩工具,JsMinGUI

    在实际开发过程中,除了使用JsMinGUI这样的压缩工具,还可以结合其他的前端构建工具,如Gulp、Grunt或Webpack,它们通常内置了JavaScript压缩插件,可以自动化整个流程,确保在部署时始终得到最小化的JavaScript文件...

    javascript代码压缩工具

    本文将详细介绍一种名为"jsMinifier"的JavaScript压缩工具,它需要在运行时安装JAVA环境。 **JSMinifier简介** JSMinifier是一款基于Java的JavaScript代码压缩工具,它可以有效地减少JavaScript文件的体积。由于它...

    IDEA类软件,js压缩插件

    "IDEA类软件,js压缩插件" 提供了一种便捷的方式来优化前端项目中的JavaScript(js)和SCSS(一种预处理器CSS的语法)文件,通过自动化压缩来减少文件大小,从而加快页面加载速度,提高用户体验。这款插件适用于那些...

    基于javascript的压缩和解压缩以及文件系统的demo

    1. **JavaScript压缩与解压缩**: - **zip.js**: 这个文件可能是实现zip文件读取和写入的库。它可能包含了用于压缩和解压缩数据的算法,如Deflate和Inflate,这些算法通常用于ZIP格式。Deflate是ZIP文件中常用的...

    Eclipse配置Javascript开发环境图文教程

    首先,我们需要安装Spket插件,Spket是一个为Eclipse提供的JavaScript开发工具包,它提供了代码补全、验证等功能,能够极大提高JavaScript开发的效率。安装Spket的过程这里不再详细说明,一旦安装完成,即可进行后续...

    javascript格式化和压缩工具

    常见的JavaScript压缩工具有UglifyJS、Terser和Google的Closure Compiler。UglifyJS和Terser都是基于JavaScript的压缩工具,它们能处理ES6以上的语法特性,而Closure Compiler则是由Google提供的一个强大的...

    压缩加密JS脚本C#源码

    这样的工具在开发Web应用程序时非常有用,因为压缩JS可以减少文件大小,提高网页加载速度,而加密则可以保护代码不被轻易读取或修改。 在描述中提到的“自动压缩JS脚本”,意味着该源码实现了自动化处理功能,能够...

    javascript压缩工具

    聚问网络开发的js压缩专家(JsPacker)v1.0 是同功能的桌面程序,并且是绿色软件,使用起来更加方便。 软件名称:js压缩专家 v1.0 (英文名称:JsPacker) 软件简介:可以高效的压缩Javascript脚本文件缩短网页显示...

    JavaScript 代码压缩工具

    10. **选择合适的压缩工具**:市面上有许多JavaScript压缩工具,如UglifyJS、Terser、Babel Minify等,它们各有优缺点,选择时应根据项目需求和兼容性来决定。 综上所述,JavaScript代码压缩是一个综合性的过程,...

    javascript实用代码压缩工具

    5. **树摇优化**(Tree Shaking):在ES6模块系统中,可以识别并移除未被引用的导入,是现代JavaScript压缩的重要特性。 常见的JavaScript代码压缩工具有UglifyJS、Terser、Google的Closure Compiler等。这些工具...

    JavaScript解析器用于ES6的压缩器优化器和美化工具包

    Terser是一款广泛使用的JavaScript压缩工具,它支持最新的ECMAScript标准,包括ES6及之后的版本。Terser的工作原理是首先将源代码解析成抽象语法树(AST),然后对AST进行各种优化操作,最后再将优化后的AST转换回...

    js压缩混淆工具

    JavaScript(简称JS)是一种广泛用于网页和网络应用的编程语言,尤其在前端开发中不可或缺。...对于任何涉及JavaScript开发的个人或团队,掌握并合理使用这类工具都是提升开发效率和代码质量的关键步骤。

    前端开发js静态资源压缩文件

    1. **JavaScript压缩的必要性** - **提高加载速度**:压缩JavaScript文件可以减少网络传输的数据量,加快文件下载速度。 - **节省带宽**:对于移动用户或者网络环境不佳的用户,小文件意味着更少的流量消耗。 - *...

Global site tag (gtag.js) - Google Analytics