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。在项目构建中可以替你完成以上任务。
Java代码
1. <property name="yuicompressor" value="${tools}/yuicompressor-2.3.6.jar" />
2. <apply executable="java" parallel="false" verbose="true" dest="${dist}/WebRoot">
3. <fileset dir="${dist}/WebRoot">
4. <include name="modules/*.js" />
5. <include name="js/*.js" />
6. </fileset>
7. <arg line="-jar" />
8. <arg path="${yuicompressor}" />
9. <arg line="--type js --charset UTF-8 -o" />
10. <targetfile />
11. <mapper type="glob" from="*.js" to="*-m.js" />
12. </apply>
13. <concat destfile="${dist}/WebRoot/js/base.js" encoding="UTF-8" >
14. <fileset dir="${dist}/WebRoot/js">
15. <include name="*-m.js" />
16. </fileset>
17. </concat>
18. <concat destfile="${dist}/WebRoot/modules/modules.js" encoding="UTF-8" >
19. <fileset dir="${dist}/WebRoot/modules">
20. <include name="*-m.js" />
21. </fileset>
22. </concat>
23. <delete>
24. <fileset dir="${dist}/WebRoot">
25. <include name="js/*.js"/>
26. <include name="modules/*.js"/>
27. <exclude name="modules/modules.js" />
28. <exclude name="js/base.js" />
29. </fileset>
30. </delete>
2、gzip压缩。
坛子里讨论的gzip压缩有2种,
一是有的容器(服务器)提供的功能,但这个局限于特定容器。比如apache+tomcat或者resin-pro版。
二是部署前手动gzip压缩,配合servlet过滤器使用,这个能实现gzip功能,但是降低了灵活性。
我自己用的是自己的实现,采用gzip servlet filter实现。下面是我的代码参考网上内容.
1. package sh.blog.util.web.filter; 2.
3. import java.io.IOException;
4.
5. import java.util.zip.GZIPOutputStream;
6.
7. import javax.servlet.ServletOutputStream;
8.
9. public class CompressedStream extends ServletOutputStream {
10.
11. private ServletOutputStream out;
12. private GZIPOutputStream gzip;
13.
14. /**
15. * 指定压缩缓冲流
16. * @param 输出流到压缩
17. * @throws IOException if an error occurs with the {@link GZIPOutputStream}.
18. */
19. public CompressedStream(ServletOutputStream out) throws IOException {
20. this.out = out;
21. reset();
22. }
23.
24. /** @see ServletOutputStream * */
25. public void close() throws IOException {
26. gzip.close();
27. }
28.
29. /** @see ServletOutputStream * */
30. public void flush() throws IOException {
31. gzip.flush();
32. }
33.
34. /** @see ServletOutputStream * */
35. public void write(byte[] b) throws IOException {
36. write(b, 0, b.length);
37. }
38.
39. /** @see ServletOutputStream * */
40. public void write(byte[] b, int off, int len) throws IOException {
41. gzip.write(b, off, len);
42. }
43.
44. /** @see ServletOutputStream * */
45. public void write(int b) throws IOException {
46. gzip.write(b);
47. }
48.
49. /**
50. * Resets the stream.
51. *
52. * @throws IOException if an I/O error occurs.
53. */
54. public void reset() throws IOException {
55. gzip = new GZIPOutputStream(out);
56. }
57. }
1. package sh.blog.util.web.filter; 2.
3. import java.io.IOException;
4. import java.io.PrintWriter;
5.
6. import javax.servlet.ServletOutputStream;
7.
8. import javax.servlet.http.HttpServletResponse;
9. import javax.servlet.http.HttpServletResponseWrapper;
10.
11. public class CompressionResponse extends HttpServletResponseWrapper {
12.
13. protected HttpServletResponse response;
14. private ServletOutputStream out;
15. private CompressedStream compressedOut;
16. private PrintWriter writer;
17. protected int contentLength;
18.
19. /**
20. * 创建一个新的被压缩响应给HTTP
21. *
22. * @param response the HTTP response to wrap.
23. * @throws IOException if an I/O error occurs.
24. */
25. public CompressionResponse(HttpServletResponse response) throws IOException {
26. super(response);
27. this.response = response;
28. compressedOut = new CompressedStream(response.getOutputStream());
29. }
30.
31. /**
32. * Ignore attempts to set the content length since the actual content length
33. * will be determined by the GZIP compression.
34. *
35. * @param len the content length
36. */
37. public void setContentLength(int len) {
38. contentLength = len;
39. }
40.
41. /** @see HttpServletResponse * */
42. public ServletOutputStream getOutputStream() throws IOException {
43. if (null == out) {
44. if (null != writer) {
45. throw new IllegalStateException("getWriter() has already been called on this response.");
46. }
47. out = compressedOut;
48. }
49. return out;
50. }
51.
52. /** @see HttpServletResponse * */
53. public PrintWriter getWriter() throws IOException {
54. if (null == writer) {
55. if (null != out) {
56. throw new IllegalStateException("getOutputStream() has already been called on this response.");
57. }
58. writer = new PrintWriter(compressedOut);
59. }
60. return writer;
61. }
62.
63. /** @see HttpServletResponse * */
64. public void flushBuffer() {
65. try {
66. if (writer != null) {
67. writer.flush();
68. } else if (out != null) {
69. out.flush();
70. }
71. } catch (IOException e) {
72. e.printStackTrace();
73. }
74. }
75.
76. /** @see HttpServletResponse * */
77. public void reset() {
78. super.reset();
79. try {
80. compressedOut.reset();
81. } catch (IOException e) {
82. throw new RuntimeException(e);
83. }
84. }
85.
86. /** @see HttpServletResponse * */
87. public void resetBuffer() {
88. super.resetBuffer();
89. try {
90. compressedOut.reset();
91. } catch (IOException e) {
92. throw new RuntimeException(e);
93. }
94. }
95.
96. /**
97. * Finishes writing the compressed data to the output stream. Note: this
98. * closes the underlying output stream.
99. *
100. * @throws IOException if an I/O error occurs.
101. */
102. public void close() throws IOException {
103. compressedOut.close();
104. }
105. }
1. /**
2. * 如果浏览器支持解压缩,则压缩该代码
3. * @throws IOException ServletException if an error occurs with the {@link GZIPOutputStream}.
4. * 如果需要开启该过滤器,在web.xml中加入此代码
5. <filter>
6. <filter-name>gzip</filter-name>
7. <filter-class>com.strongit.finance.gzip</filter-class>
8. </filter>
9. <filter-mapping>
10. <filter-name>gzip</filter-name>
11. <url-pattern>*.jsp</url-pattern>
12. </filter-mapping>
13. */
14.
15. package sh.blog.util.web.filter;
16.
17. import java.io.IOException;
18.
19. import java.util.Enumeration;
20.
21. import javax.servlet.Filter;
22. import javax.servlet.FilterChain;
23. import javax.servlet.FilterConfig;
24. import javax.servlet.ServletException;
25. import javax.servlet.ServletRequest;
26. import javax.servlet.ServletResponse;
27.
28. import javax.servlet.http.HttpServletRequest;
29. import javax.servlet.http.HttpServletResponse;
30.
31. import org.apache.commons.logging.Log;
32. import org.apache.commons.logging.LogFactory;
33.
34.
35. public class CompressionFilter implements Filter {
36.
37. protected Log log = LogFactory.getFactory().getInstance(this.getClass().getName());
38.
39. @SuppressWarnings("unchecked")
40. public void doFilter(ServletRequest request, ServletResponse response,
41. FilterChain chain) throws IOException, ServletException {
42.
43. boolean compress = false;
44. if (request instanceof HttpServletRequest){
45. HttpServletRequest httpRequest = (HttpServletRequest) request;
46. Enumeration headers = httpRequest.getHeaders("Accept-Encoding");
47. while (headers.hasMoreElements()){
48. String value = (String) headers.nextElement();
49. if (value.indexOf("gzip") != -1){
50. compress = true;
51. }
52. }
53. }
54.
55. if (compress){//如果浏览器支持则压缩
56. HttpServletResponse httpResponse = (HttpServletResponse) response;
57. httpResponse.addHeader("Content-Encoding", "gzip");
58. CompressionResponse compressionResponse= new CompressionResponse(httpResponse);
59. chain.doFilter(request, compressionResponse);
60. compressionResponse.close();
61. }
62. else{//如果浏览器不支持则不压缩
63. chain.doFilter(request, response);
64. }
65. }
66.
67.
68. public void init(FilterConfig config) throws ServletException {
69.
70. }
71.
72. public void destroy(){
73.
74. }
75. }
实际使用的效果以http://demo.slivercrm.cn:8084 为例