高性能WEB开发之JS、CSS的合并压缩

开发 前端
本篇文章主要讨论下目前JS,CSS 合并、压缩、缓存管理存在的一些问题,然后分享下自己项目中用到的1个处理方案,并提供1个实例下载。

存在的问题:

合并、压缩文件主要有2方面的问题:

1. 每次发布的时候需要运行一下自己写的bat文件或者其他程序把文件按照自己的配置合并和压缩。

2. 因生产环境和开发环境需要加载的文件不一样,生产环境为了需要加载合并、压缩后的文件,而开发环境为了修改、调试方便,需要加载非合并、压缩的文件,所以我们常常需要在JSP中类似与下面的判断代码:

  1. <c:if test="${env=='prod'}"> 
  2.    <script type="text/javascript" src="/js/all.js"></script> 
  3. </c:if> 
  4. <c:if test="${env=='dev'}"> 
  5.    <script type="text/javascript" src="/js/1.js"></script> 
  6.    <script type="text/javascript" src="/js/2.js"></script> 
  7.    <script type="text/javascript" src="/js/3.js"></script> 
  8. </c:if> 

缓存问题:在现在JS满天飞的时代,大家都知道缓存能带来的巨大好处,但缓存确实非常麻烦的一个问题,相信很多人曾经历过下面的情况:为了让程序更快,在服务器上为JS加上缓冲5天的代码,但产品更新后第二天就接到电话说系统出错,详细了解后就发现是缓存引起的,让用户删除缓存后就会OK。原因很简单,就是你JS已经修改了,但用户还在使用缓存中的老JS。在经历几次这种情况,被领导数落了几次后。没办法只能把JS的缓冲去掉,或者改成8个小时。可这样就完全失去了缓存的优势了,哪我们到底需要解决哪些问题才能让我们使用缓冲顺心如意了?

1. 如何在修改了某个JS后,自动把所有引用该JS页面的代码中加上1个版本号?

2. 该如何生成版本号,根据什么来产生这个版本号。

可能有人为了解决上面的缓存问题,写了个JSP标签,通过标签读取JS、css文件的修改时间来作为版本号,从而来解决上面2个问题。但这种方法有下面几个缺点:

1. 每次请求都要通过标签读取读取文件的修改时间,速度慢。当然你可以把文件的修改时间放到缓存中,这样也会加到了内存使用量。

2. 在HTML静态页面中用不了

3. 如果你们公司是如下的部署发布方式(我们公司就是这样),则会失效。每次发布,不是直接覆盖之前的WEB目录,运维的为的发布方便,要求每次发布直接给他们1个war包,他们会把之前WEB目录整个删除,然后上传现在的war包,这样就导致程序运行后,所有文件的***修改时间都是解压war的时间。

分享自己项目中的处理方案:

为了解决上面讨论过的问题,在下写了1个如下的组件,组件中根据我们自己的实际情况使用了文件大小来做为文件的版本号,虽然在文件修改很小(比如把字符a改成b),可能文件大小并没有变,导致版本号也不会变。

但这种机率还是非常低的。当然如果你觉的使用文件修改时间作为版本号适合你,只需要修改一行代码就行,下面看下这个组件的处理流程(本来想用流程图表达,***还是觉的文字来的直白写):

1. 程序启动(contextInitialized)

2. 搜索程序目录下的所有merge.txt文件,根据merge.txt文件的配置合并文件, merge.txt文件实例如下:

# 文件合并配置文件,多个文件以|隔开,以/开头的表示从根目录开始,

# 空格之后的文件名表示合并之后的文件名

# 把1,2,3合并到all文件中

1.js|2.js|3.js all.js

#合并CSS

/css/mian.css|/css/common.css all.css

3. 搜索程序目录下所有JS,CSS文件(包括合并后的),每个文件都压缩后生成对应的1个新文件。

4. 搜索程序目录下所有JSP,html文件,把所有JS,css的引用代码改成压缩后并加了版本号的引用。

实例:

 

实例的文件结构如下图:

JS、CSS的合并、压缩、缓存管理

看JSP原始代码(程序运行前):

  1. <%@page contentType="text/html" pageEncoding="UTF-8"%> 
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd"> 
  3. <% boolean isDev = false;  // 是否开发环境%> 
  4. <html> 
  5.     <head> 
  6.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  7.         <title>JSP Page</title> 
  8.         <% if(isDev){ %> 
  9.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.4.2.js"></script> 
  10.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/1.js"></script> 
  11.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/2.js"></script> 
  12.         <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/1.css" /> 
  13.         <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/2.css" /> 
  14.         <% }else{ %> 
  15.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.4.2.js"></script> 
  16.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/all.js"></script> 
  17.         <link type="text/css" rel="stylesheet"  href="<%=request.getContextPath() %>/css/all.css" /> 
  18.         <% } %> 
  19.     </head> 
  20.     <body> 
  21.         <h1 class="c1">Hello World!</h1> 
  22.     </body> 
  23. </html> 

程序运行后JSP的代码:

  1. <%@page contentType="text/html" pageEncoding="UTF-8"%> 
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
  3. <%  
  4.     boolean isDev = false;  // 是否开发环境  
  5. %> 
  6. <html> 
  7.     <head> 
  8.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
  9.         <title>JSP Page</title> 
  10.         <% if(isDev){ %> 
  11.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.4.2-3gmin.js?99375"></script> 
  12.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/1-3gmin.js?90"></script> 
  13.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/2-3gmin.js?91"></script> 
  14.         <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/1-3gmin.css?35" /> 
  15.         <link type="text/css" rel="stylesheet" href="<%=request.getContextPath() %>/css/2-3gmin.css?18" /> 
  16.         <% }else{ %> 
  17.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-1.4.2-3gmin.js?99375"></script> 
  18.         <script type="text/javascript" src="<%=request.getContextPath() %>/js/all-3gmin.js?180"></script> 
  19.         <link type="text/css" rel="stylesheet"  href="<%=request.getContextPath() %>/css/all-3gmin.css?53" /> 
  20.         <% } %> 
  21.     </head> 
  22.     <body> 
  23.         <h1 class="c1">Hello World!</h1> 
  24.     </body> 
  25. </html> 

加3gmin后缀的文件全部是程序启动时自动生成的。

实例下载:猛击此处下载

系列文章:

高性能WEB开发之减少请求、响应的数据量

高性能WEB开发之如何减少请求数

高性能WEB开发之如何加载JavaScript

高性能WEB开发之图片篇

高性能WEB开发之Web性能测试工具推荐

高性能WEB开发之HTTP服务器

责任编辑:陈贻新 来源: BearRui的博客
相关推荐

2011-04-27 10:57:29

高性能web开发

2011-04-18 10:16:30

WEB高性能

2011-04-07 13:53:25

Web工具

2011-10-18 13:58:32

高性能web

2011-04-19 11:06:03

JavaScriptweb

2011-04-21 09:59:48

WEBjavascript

2011-04-07 13:39:24

WebHTTP

2011-06-14 09:27:43

高性能WEB开发

2013-09-10 16:16:19

移动网站性能优化移动web

2011-04-21 10:47:29

Webjavascript

2011-04-25 10:11:57

高性能web开发

2011-04-28 09:40:26

flush高性能Web开发

2009-07-30 10:28:56

Web高性能开发

2016-08-23 14:37:21

2013-06-19 09:20:53

Web开发Web性能优化高性能

2016-11-28 09:19:27

2013-08-16 14:43:14

高性能移动Web移动Web站点移动Web

2013-09-10 17:13:57

移动网站性能优化移动web

2014-03-19 14:34:06

JQuery高性能

2019-03-14 15:38:19

ReactJavascript前端
点赞
收藏

51CTO技术栈公众号