The crazy HTML compression _javascript technique of web high performance development

Source: Internet
Author: User
Generally we start gzip less on the HTML start gzip, because now the HTML is dynamic, will not use browser caching, and enable gzip every request need compression, will be compared to consume server resources, to JS,CSS start gzip is better because JS, CSS will use caching. I personally think the biggest advantage of compressed HTML is lucrative, as long as the written once, all future programs can be used, will not add any additional development work.
In the "JS, CSS Merge, compress, cache management" in the article said that they have written 1 automatic merge, compression js,css, and add version number of components. This time, the functionality of compressing HTML is added to the component, and the process is simply to scan all html,jsp (ASPX) for compression when the program starts (contextinitialized or Application_Start).
Considerations for Compression:
The main way to implement it is to use regular expressions to find, replace. In HTML compression, the main attention to the following points:
1. The content format of the Pre,textarea label needs to be preserved and cannot be compressed.
2. When the HTML annotation is removed, some annotations cannot be removed, such as:<!--[if IE 6]> ... <! [endif]-->
3. Compress embedded JS in the comments to note, because the possible annotation symbol will appear in the string, such as: var url = "Http://www.cnblogs.com"; Front//is not a comment
When you remove the JS line break, you can not directly follow the action content, you need to have a space, consider the following code:
Else
Return
If you do not take a space, it becomes elsereturn.
4. JSP (ASPX) is likely to use <%%> embed some server code, this time also need to handle separately, the comments in the processing method with the same as JS.
Source:
The following is the Java implementation of the source code, you can also click here to download the code, I believe we all understand, it is easy to change into net code:
Copy Code code as follows:

Import Java.io.StringReader;
Import Java.io.StringWriter;
Import java.util.*;
Import java.util.regex.*;
/*******************************************
* Compress the code in jsp,html, remove all whitespace, line feed
* @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);
Single-line Comment,
private static Pattern Signlecommentpattern = Pattern.compile ("//.*");
String matching
private static Pattern Stringpattern = Pattern.compile ("(\) [^\" \\n]*?\ "|" [^ ' \\n]* ']);
Trim go to spaces and line breaks
private static Pattern Trimpattern = Pattern.compile ("\\n\\s*", pattern.multiline);
private static Pattern trimPattern2 = Pattern.compile ("\\s*\\r", pattern.multiline);
Multiline Comment
private static Pattern Multicommentpattern = Pattern.compile ("/\\*.*?\\*/", Pattern.dotall | pattern.case_insensitive | Pattern.multiline);
private static String Tempsinglecommentblock = "%%%htmlcompress~singlecomment&&&"; Placeholder
private static String TempMulitCommentBlock1 = "%%%htmlcompress~mulitcomment1&&&"; /* Placeholder
private static String TempMulitCommentBlock2 = "%%%htmlcompress~mulitcomment2&&&"; */Placeholder

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
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
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
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
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
while (Result.contains (Tempstyleblock)) {
result = Result.replacefirst (Tempstyleblock, Matcher.quotereplacement (blocks.remove (0)));
}
return result;
}
private static string compressjsp (string source) {
Check if block are 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 are 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 are not empty
Matcher Stylematcher = stylepattern.matcher (source);
if (Stylematcher.find ()) {
Get rid of comments, line wrap
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;
Because the annotation conforms to the possibility of appearing in the string, the special character in the string should be removed first.
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);
}
}
Remove comments
result = Signlecommentpattern.matcher (result). ReplaceAll ("");
result = Multicommentpattern.matcher (result). ReplaceAll ("");
result = Trimpattern2.matcher (result). ReplaceAll ("");
result = Trimpattern.matcher (result). ReplaceAll ("");
Recover the replaced string
result = Result.replaceall (Tempsinglecommentblock, "//"). ReplaceAll (TempMulitCommentBlock1, "*")
. ReplaceAll (TempMulitCommentBlock2, "* *");
return result;
}
}

Usage considerations:

Use the above method, then run the program, it is not found that each page to see the source code when all become 1 lines, it is not bad, but in the use of the time to pay attention to some problems:
1. Embed JS originally want to call yuicompressor to compress, Yuicompressor compression JS before, will first compile JS is legitimate, because we embed JS may be used a lot of server-side code, such as var now = <%=datetime.now %>, such code compiles and does not pass, so the yuicompressor cannot be used.
Finally can write their own compressed JS code, their own write more coarse, so there is a problem is also resolved, is that if the developer in a JS code after the addition of a semicolon, compressed into 1 lines is very likely to go wrong. So use this to make sure that each statement ends with a semicolon.

2. Because it compresses all JSP (ASPX) when the program is started, the HTML that is generated dynamically when the user requests it is not compressed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.