- 浏览: 814274 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yuhanwm910731:
我现在需要实现复选(非级联选择)的树形下拉菜单,麻烦发给我一份 ...
extjs3.X支持树型的下拉控件 -
shine1200:
“所以咱们现在设置的虚拟路径“/message/upload/ ...
weblogic虚拟路径的配置和使用(2) -
icefireforest:
Fangrn 写道jx_dream 写道楼主,我最近在做树形下 ...
extjs3.X支持树型的下拉控件 -
cloudfile:
谢谢分享!
c++库c#调用开发时需要注意的一点 -
xuweilinbegin:
我也要一份哦:xuweilin15353@163.com,谢谢 ...
extjs3.X支持树型的下拉控件
前言:
上一篇随笔中网友 skyaspnet 问我如何压缩HTML,当时回答是推荐他使用gzip,后来想想,要是能把所有的 html,jsp(aspx)在运行前都压缩成1行未免不是一件好事啊。一般我们启动gzip都比较少对html启动gzip,因为现在的html都是动 态的,不会使用浏览器缓存,而启用gzip的话每次请求都需要压缩,会比较消耗服务器资源,对js,css启动gzip比较好是因为js,css都会使用 缓存。我个人觉得的压缩html的最大好处就是一本万利,只要写好了一次,以后所有程序都可以使用,不会增加任何额外的开发工作。
在“JS、CSS的合并、压缩、缓存管理 ”一文中说到自己写过的1个自动合并、压缩JS,CSS,并添加版本号的组件。这次把压缩 html的功能也加入到该组件中,流程很简单,就是在程序启动(contextInitialized or Application_Start)的时候扫描所有html,jsp(aspx)进行压缩。
压缩的注意事项:
实现的方式主要是用正则表达式去查找,替换。在html压缩的时候,主要要注意下面几点:
1. pre,textarea 标签里面的内容格式需要保留,不能压缩。
2. 去掉html注释的时候,有些注释是不能去掉的,比如:<!--[if IE 6]> ..... <![endif]-->
3. 压缩嵌入式js中的注释要注意,因为可能注释符号会出现在字符串中,比如: var url = "http://www.cnblogs.com"; // 前面的//不是注释
去掉JS换行符的时候,不能直接跟一下行动内容,需要有空格,考虑下面的代码:
else
return;
如果不带空格,则变成elsereturn。
4. jsp(aspx) 中很有可能会使用<% %>嵌入一些服务器代码,这个时候也需要单独处理,里面注释的处理方法跟js的一样。
源代码:
下面是java实现的源代码,也可以 猛击此处 下载该代码,相信大家都看的懂,也很容易改成net代码:
import java.io.StringReader; import java.io.StringWriter; import java.util.*; import java.util.regex.*; /******************************************* * 压缩jsp,html中的代码,去掉所有空白符、换行符 * @author bearrui(ak-47) * @version 0.1 * @date 2010-5-13 *******************************************/ public class HtmlCompressor { private static String tempPreBlock = "%%%HTMLCOMPRESS~PRE&&&"; private static String tempTextAreaBlock = "%%%HTMLCOMPRESS~TEXTAREA&&&"; private static String tempScriptBlock = "%%%HTMLCOMPRESS~SCRIPT&&&"; private static String tempStyleBlock = "%%%HTMLCOMPRESS~STYLE&&&"; private static String tempJspBlock = "%%%HTMLCOMPRESS~JSP&&&"; private static Pattern commentPattern = Pattern.compile("<!--\\s*[^\\[].*?-->", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static Pattern itsPattern = Pattern.compile(">\\s+?<", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static Pattern prePattern = Pattern.compile("<pre[^>]*?>.*?</pre>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static Pattern taPattern = Pattern.compile("<textarea[^>]*?>.*?</textarea>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static Pattern jspPattern = Pattern.compile("<%([^-@][\\w\\W]*?)%>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); // <script></script> private static Pattern scriptPattern = Pattern.compile("(?:<script\\s*>|<script type=['\"]text/javascript['\"]\\s*>)(.*?)</script>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static Pattern stylePattern = Pattern.compile("<style[^>()]*?>(.+)</style>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); // 单行注释, private static Pattern signleCommentPattern = Pattern.compile("//.*"); // 字符串匹配 private static Pattern stringPattern = Pattern.compile("(\"[^\"\\n]*?\"|'[^'\\n]*?')"); // trim去空格和换行符 private static Pattern trimPattern = Pattern.compile("\\n\\s*",Pattern.MULTILINE); private static Pattern trimPattern2 = Pattern.compile("\\s*\\r",Pattern.MULTILINE); // 多行注释 private static Pattern multiCommentPattern = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); private static String tempSingleCommentBlock = "%%%HTMLCOMPRESS~SINGLECOMMENT&&&"; // //占位符 private static String tempMulitCommentBlock1 = "%%%HTMLCOMPRESS~MULITCOMMENT1&&&"; // /*占位符 private static String tempMulitCommentBlock2 = "%%%HTMLCOMPRESS~MULITCOMMENT2&&&"; // */占位符 public static String compress(String html) throws Exception { if(html == null || html.length() == 0) { return html; } List<String> preBlocks = new ArrayList<String>(); List<String> taBlocks = new ArrayList<String>(); List<String> scriptBlocks = new ArrayList<String>(); List<String> styleBlocks = new ArrayList<String>(); List<String> jspBlocks = new ArrayList<String>(); String result = html; //preserve inline java code Matcher jspMatcher = jspPattern.matcher(result); while(jspMatcher.find()) { jspBlocks.add(jspMatcher.group(0)); } result = jspMatcher.replaceAll(tempJspBlock); //preserve PRE tags Matcher preMatcher = prePattern.matcher(result); while(preMatcher.find()) { preBlocks.add(preMatcher.group(0)); } result = preMatcher.replaceAll(tempPreBlock); //preserve TEXTAREA tags Matcher taMatcher = taPattern.matcher(result); while(taMatcher.find()) { taBlocks.add(taMatcher.group(0)); } result = taMatcher.replaceAll(tempTextAreaBlock); //preserve SCRIPT tags Matcher scriptMatcher = scriptPattern.matcher(result); while(scriptMatcher.find()) { scriptBlocks.add(scriptMatcher.group(0)); } result = scriptMatcher.replaceAll(tempScriptBlock); // don't process inline css Matcher styleMatcher = stylePattern.matcher(result); while(styleMatcher.find()) { styleBlocks.add(styleMatcher.group(0)); } result = styleMatcher.replaceAll(tempStyleBlock); //process pure html result = processHtml(result); //process preserved blocks result = processPreBlocks(result, preBlocks); result = processTextareaBlocks(result, taBlocks); result = processScriptBlocks(result, scriptBlocks); result = processStyleBlocks(result, styleBlocks); result = processJspBlocks(result, jspBlocks); preBlocks = taBlocks = scriptBlocks = styleBlocks = jspBlocks = null; return result.trim(); } private static String processHtml(String html) { String result = html; //remove comments // if(removeComments) { result = commentPattern.matcher(result).replaceAll(""); // } //remove inter-tag spaces // if(removeIntertagSpaces) { result = itsPattern.matcher(result).replaceAll("><"); // } //remove multi whitespace characters // if(removeMultiSpaces) { result = result.replaceAll("\\s{2,}"," "); // } return result; } private static String processJspBlocks(String html, List<String> blocks){ String result = html; for(int i = 0; i < blocks.size(); i++) { blocks.set(i, compressJsp(blocks.get(i))); } //put preserved blocks back while(result.contains(tempJspBlock)) { result = result.replaceFirst(tempJspBlock, Matcher.quoteReplacement(blocks.remove(0))); } return result; } private static String processPreBlocks(String html, List<String> blocks) throws Exception { String result = html; //put preserved blocks back while(result.contains(tempPreBlock)) { result = result.replaceFirst(tempPreBlock, Matcher.quoteReplacement(blocks.remove(0))); } return result; } private static String processTextareaBlocks(String html, List<String> blocks) throws Exception { String result = html; //put preserved blocks back while(result.contains(tempTextAreaBlock)) { result = result.replaceFirst(tempTextAreaBlock, Matcher.quoteReplacement(blocks.remove(0))); } return result; } private static String processScriptBlocks(String html, List<String> blocks) throws Exception { String result = html; // if(compressJavaScript) { for(int i = 0; i < blocks.size(); i++) { blocks.set(i, compressJavaScript(blocks.get(i))); } // } //put preserved blocks back while(result.contains(tempScriptBlock)) { result = result.replaceFirst(tempScriptBlock, Matcher.quoteReplacement(blocks.remove(0))); } return result; } private static String processStyleBlocks(String html, List<String> blocks) throws Exception { String result = html; // if(compressCss) { for(int i = 0; i < blocks.size(); i++) { blocks.set(i, compressCssStyles(blocks.get(i))); } // } //put preserved blocks back while(result.contains(tempStyleBlock)) { result = result.replaceFirst(tempStyleBlock, Matcher.quoteReplacement(blocks.remove(0))); } return result; } private static String compressJsp(String source) { //check if block is not empty Matcher jspMatcher = jspPattern.matcher(source); if(jspMatcher.find()) { String result = compressJspJs(jspMatcher.group(1)); return (new StringBuilder(source.substring(0, jspMatcher.start(1))).append(result).append(source.substring(jspMatcher.end(1)))).toString(); } else { return source; } } private static String compressJavaScript(String source) { //check if block is not empty Matcher scriptMatcher = scriptPattern.matcher(source); if(scriptMatcher.find()) { String result = compressJspJs(scriptMatcher.group(1)); return (new StringBuilder(source.substring(0, scriptMatcher.start(1))).append(result).append(source.substring(scriptMatcher.end(1)))).toString(); } else { return source; } } private static String compressCssStyles(String source) { //check if block is not empty Matcher styleMatcher = stylePattern.matcher(source); if(styleMatcher.find()) { // 去掉注释,换行 String result= multiCommentPattern.matcher(styleMatcher.group(1)).replaceAll(""); result = trimPattern.matcher(result).replaceAll(""); result = trimPattern2.matcher(result).replaceAll(""); return (new StringBuilder(source.substring(0, styleMatcher.start(1))).append(result).append(source.substring(styleMatcher.end(1)))).toString(); } else { return source; } } private static String compressJspJs(String source){ String result = source; // 因注释符合有可能出现在字符串中,所以要先把字符串中的特殊符好去掉 Matcher stringMatcher = stringPattern.matcher(result); while(stringMatcher.find()){ String tmpStr = stringMatcher.group(0); if(tmpStr.indexOf("//") != -1 || tmpStr.indexOf("/*") != -1 || tmpStr.indexOf("*/") != -1){ String blockStr = tmpStr.replaceAll("//", tempSingleCommentBlock).replaceAll("/\\*", tempMulitCommentBlock1) .replaceAll("\\*/", tempMulitCommentBlock2); result = result.replace(tmpStr, blockStr); } } // 去掉注释 result = signleCommentPattern.matcher(result).replaceAll(""); result = multiCommentPattern.matcher(result).replaceAll(""); result = trimPattern2.matcher(result).replaceAll(""); result = trimPattern.matcher(result).replaceAll(" "); // 恢复替换掉的字符串 result = result.replaceAll(tempSingleCommentBlock, "//").replaceAll(tempMulitCommentBlock1, "/*") .replaceAll(tempMulitCommentBlock2, "*/"); return result; } }
使用注意事项 :
使用了上面方法后,再运行程序,是不是发现每个页面查看源代码的时候都变成1行啦,还不错吧,但是在使用的时候还是要注意一些问题:
1. 嵌入js本来想调用yuicompressor来压缩,yuicompressor压缩JS前,会先编译js是否合法,因我们嵌入的js中可能很多会用到 一些服务器端代码,比如 var now = <%=DateTime.now %> ,这样的代码会编译不通过,所以无法使用yuicompressor。
最后只能自己写压缩JS代码,自己写的比较粗燥,所以有个问题还解决,就是如果开发人员在一句js代码后面没有加分号的话,压缩成1行就很有可能出问 题。所以使用这个需要保证每条语句结束后都必须带分号。
2. 因为是在程序启动的时候压缩所有jsp(aspx),所以如果是用户请求的时候动态产生的html就无法压缩。
发表评论
-
提供IT系统运维支持、系统优化方案
2012-10-26 14:46 6提供IT系统运维支持、系统优化方案,有多个运维实施经验。 ... -
Java指定编码读写文件(UTF-8)
2010-11-30 14:00 3129有时我们需要程序动态生成jsp文件,采取系统默认的编码操作的文 ... -
was6.0发布struts2项目异常
2010-11-18 18:39 2011[10-11-18 18:31:33:609 CST] 000 ... -
利用spring提供的字符编码过滤器
2010-11-14 11:55 2024<!-- spring的字符集过滤器 --> ... -
简单的几句CSS布局口诀
2010-11-10 16:41 1027简单的几句CSS布局口诀,就可以写出精简,标准的样式。 ... -
commons-email笔记
2010-11-10 14:38 1395import java.io.UnsupportedE ... -
如何解决 调用jar程序时出现 outofMemory的问题
2010-10-29 12:02 1254我们在调用 打包好的java程序时,如果程序要加载大量数据的话 ... -
GC策略的调优
2010-09-30 22:30 1651GC 策略在 G1 还没成熟的情况下,目前主要有串行、并 ... -
关于Spring和WebLogic版本兼容的一点小提示
2010-09-30 16:31 2090首先 WebLogic 的各个版本和 JDK 绑定的很紧, 或 ... -
删除WebLogic 10的缓存
2010-09-30 16:07 4663在WebLogic 10上部署了一个应用,最近作了更新并重新部 ... -
weblogic如何强制先加载web-inf/lib下的jar
2010-09-30 16:05 4820方法1: 修改WEB-INF\weblogic.xml (如 ... -
用Log4j自动生成日志
2010-09-27 13:28 1670Log4j是Apache基金会的一 ... -
java smslib发送短信
2010-09-10 10:02 1653public class SendMessage { ... -
Spring定时器的两种实现方式
2010-09-01 21:07 1504有两种流行Spring定时 ... -
使用 Commons-Email 在邮件内容中直接嵌入图片
2010-08-31 20:25 1354我们在发送邮件的时候,如果使用HTML在邮件内容中嵌入图片,& ... -
Struts2中转换Date类型的问题
2010-08-29 09:43 1387Web开发会涉及到很多类型转换的情况。我们知道,页面中的一切值 ... -
java smslib 发送短信错误信息
2010-08-25 15:02 4266org.smslib.GatewayException: GS ... -
rxtx取代javax.comm实现Java跨平台设备端口通信
2010-08-24 08:53 2183From Rxtx <!-- start conte ... -
javascript汉字转拼音代码
2010-08-22 08:21 4600使用方法(1):pinyin.go('汉字'); //例:张家 ... -
关于IE等浏览器在下载JAR文件时的,将后缀更改为zip等问题及解决方案
2010-08-03 12:19 1235httpd.conf这个文件中的mime.types上面,打开 ...
相关推荐
在WEB高性能开发中,疯狂的HTML压缩指的是将网页中的多余空白字符、换行符甚至注释等内容去掉,以降低页面文件的大小,提升用户体验。 通常,HTML压缩可以通过多种方式实现,比如使用HTTP协议中的gzip压缩。gzip...
在Web前端开发中,高质量的代码意味着代码具有良好的可读性、可维护性、可扩展性和高性能。以下是一些可能在文档中涉及的关键知识点: 1. **代码结构与组织**:良好的代码结构可以使项目更易于理解和修改。这可能...
HTML5移动Web开发是当前互联网应用开发的重要领域,随着移动设备的普及,越来越多的开发者将目光转向了构建适应各种...通过学习,你可以掌握创建高性能、跨平台的移动Web应用所需的知识,为你的职业发展打下坚实基础。
百度地图鹰眼web轨迹管理台V3.zip"是一个以Web为基础,利用百度地图鹰眼服务进行轨迹管理的开源项目,涵盖了Web开发、GIS集成、API接口设计等多个技术领域,对于希望在Web应用中集成轨迹管理功能的开发者具有很高的...
6. **性能优化**:优化Web应用加载速度和运行效率是开发过程中的重要环节。这包括合理使用缓存、减少HTTP请求、压缩资源文件等策略。 7. **安全考虑**:由于WebView直接执行用户提供的HTML和JavaScript,开发者需要...
【标题】:“Web期末作业设计网页 - Mast开发笔记” 在这个项目中,我们主要探讨的是一个基于Web技术的期末作业设计,特别关注Mast开发方法。Mast,全称为“模块化、可扩展、可维护、可测试”的开发模式,是一种在...
总结来说,`wheezy.web`是针对Python 3.2的Web开发框架,具备轻量级、高性能的特性,适用于构建HTTP服务器和Web应用。用户可以通过解压缩`.egg`文件并在Python环境中安装使用。它属于Python后端开发的一部分,但与...
在智能手机和移动设备普及的今天,构建高性能的移动Web成为了前端开发人员所面临的一项重要任务。移动Web能够覆盖更广泛的用户群体,并且可以跨平台运行,而不像原生应用那样受限于特定的操作系统。腾讯作为一家领先...
9. 性能优化:介绍Flask应用的性能优化方法,包括缓存使用、数据库查询优化、资源压缩等。 10. 生产部署:提供关于如何将Flask应用部署到生产环境的指导,包括选择合适的服务器、配置Web服务器(如Gunicorn或uWSGI...
总的来说,《构建高性能Web站点》是一本全面覆盖Web性能优化的指南,无论你是开发人员、运维工程师还是网站管理员,都能从中受益,学习到提升Web站点性能的实用技术和最佳实践。通过本书的学习,你将能够创建出更...
另外,WebAssembly使得运行高性能计算任务成为可能,Web Components允许创建可重用的自定义元素,提升了代码复用性和组件化开发。 最后,安全性是移动Web开发不可忽视的一环。了解XSS、CSRF等常见攻击,以及如何...
### 高性能Web开发之减少请求数策略详解 #### 一、引言 随着互联网技术的飞速发展,Web应用已经成为人们日常生活中不可或缺的一部分。然而,随着网页内容的日益丰富,网页加载速度逐渐成为用户体验的重要因素之一。...
《移动Web前端高效开发实战》是一本专注于提升移动端Web应用开发效率的专业书籍,其源码提供了丰富的实践案例和代码示例,旨在帮助开发者掌握在移动设备上构建高性能、响应式和用户友好的Web应用的技巧。书中涉及的...
"最流行的web开发前端HTML模板"指的是那些被广泛采用,拥有高度可定制性、易用性和良好性能的HTML模板。这些模板通常集成了最新的HTML5技术和CSS3样式规则,能够帮助开发者构建出响应式的网页,适应不同设备的屏幕...
《高性能HTML5.Pro HTML5 Performance》是一本深入探讨如何优化HTML5应用性能的专业书籍。它主要针对开发者,尤其是那些致力于创建高效、流畅的Web体验的技术人员。HTML5作为现代Web开发的标准,其性能优化是提升...
百度作为中国领先的互联网巨头,其Web-App-Developer项目致力于提供前沿的前端开发工具和技术支持,帮助开发者构建高性能、用户体验优秀的Web应用程序。在这个领域,我们主要关注以下几个核心知识点: 1. HTML5与...