真有必要去除HTML中的空白字符吗?
2009-12-07 17:59 Jeffrey Zhao 阅读(14884) 评论(52) 编辑 收藏 举报刚才有朋友在MSN上问我说,他的页面中有许多空白字符,打开源文件一看发现这代码稀疏得很。他觉得很浪费,他说有什么办法可以去除它们。我问他“你的页面使用GZip压缩了吗?”他说用了,于是我回答说“那么就不用去除空白字符了,连续空白字符压缩得很好,去掉后效果不大的”。这时我又不禁想到早上那篇《博客园首页优化心得》中也有一条是“去除HTML中的空格、空行”,于是我便打算尝试一下,去除空白字符到底有多少效果。
我的实验目标是我博客的前40篇文章的详细页,未压缩前的体积从98K到277K不等,我想也应该算是博客园中比较典型的页面大小吧。我使用这样的测试代码:
static void Main() { var files = Directory.GetFiles(@"d:\pages"); foreach (var f in files) Compare(File.ReadAllText(f)); Console.WriteLine("Press enter to exit..."); Console.ReadLine(); } private static readonly Regex REGEX_LINE_BREAKS = new Regex(@"\n\s*", RegexOptions.Compiled); private static readonly Regex REGEX_LINE_SPACE = new Regex(@"\n\s*\r", RegexOptions.Compiled); private static readonly Regex REGEX_SPACE = new Regex(@"( )+", RegexOptions.Compiled); private static void Compare(string html) { long original, compressedOriginal; GetLength(html, out original, out compressedOriginal); long stripped, compressedStripped; html = REGEX_LINE_BREAKS.Replace(html, ""); html = REGEX_LINE_SPACE.Replace(html, ""); html = REGEX_SPACE.Replace(html, " "); GetLength(html, out stripped, out compressedStripped); Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", original, compressedOriginal, stripped, compressedStripped, original - stripped, compressedOriginal - compressedStripped); } private static void GetLength(string html, out long original, out long compressed) { var bytes = Encoding.UTF8.GetBytes(html); var stream = new MemoryStream(); var gzipStream = new GZipStream(stream, CompressionMode.Compress); gzipStream.Write(bytes, 0, bytes.Length); gzipStream.Flush(); original = bytes.LongLength; compressed = stream.Length; }
在上面这段代码里我使用的是博客园去空白字符的方法,结果如下:
原页面 | 原页面(压缩) | 去空白后 | 去空白后(压缩) | 去空白前后 | 去空白前后(压缩) |
---|---|---|---|---|---|
130760 | 36018 | 117354 | 34702 | 13406 | 1316 |
255935 | 63406 | 240433 | 61870 | 15502 | 1536 |
278871 | 86794 | 263704 | 85298 | 15167 | 1496 |
221248 | 53148 | 205440 | 51548 | 15808 | 1600 |
151612 | 40260 | 137939 | 38940 | 13673 | 1320 |
135019 | 36000 | 121593 | 34750 | 13426 | 1250 |
128239 | 36230 | 114658 | 34878 | 13581 | 1352 |
161530 | 42776 | 147189 | 41392 | 14341 | 1384 |
99884 | 28372 | 87047 | 27084 | 12837 | 1288 |
173534 | 43724 | 158446 | 42272 | 15088 | 1452 |
191519 | 50398 | 176958 | 48888 | 14561 | 1510 |
176996 | 40274 | 162706 | 38978 | 14290 | 1296 |
206348 | 47362 | 191400 | 45964 | 14948 | 1398 |
137014 | 38608 | 122855 | 37076 | 14159 | 1532 |
144715 | 37260 | 131097 | 35748 | 13618 | 1512 |
146531 | 36704 | 132619 | 35302 | 13912 | 1402 |
199915 | 49224 | 182227 | 47452 | 17688 | 1772 |
106929 | 29850 | 93690 | 28518 | 13239 | 1332 |
136264 | 36664 | 121548 | 34990 | 14716 | 1674 |
148750 | 37990 | 134567 | 36578 | 14183 | 1412 |
282886 | 71924 | 266336 | 70306 | 16550 | 1618 |
176099 | 41468 | 161322 | 40126 | 14777 | 1342 |
108394 | 30456 | 95428 | 29216 | 12966 | 1240 |
152578 | 40186 | 138543 | 38866 | 14035 | 1320 |
230243 | 59970 | 215389 | 58554 | 14854 | 1416 |
251183 | 57156 | 234862 | 55694 | 16321 | 1462 |
196957 | 48176 | 181608 | 46776 | 15349 | 1400 |
172267 | 41340 | 158105 | 40056 | 14162 | 1284 |
265877 | 63650 | 248974 | 62142 | 16903 | 1508 |
147403 | 38894 | 133751 | 37492 | 13652 | 1402 |
149091 | 36460 | 134998 | 35190 | 14093 | 1270 |
167741 | 43200 | 153614 | 41856 | 14127 | 1344 |
171564 | 40898 | 157333 | 39648 | 14231 | 1250 |
125812 | 34570 | 111047 | 33200 | 14765 | 1370 |
190649 | 46524 | 175197 | 45040 | 15452 | 1484 |
153807 | 39462 | 139401 | 38054 | 14406 | 1408 |
120788 | 32228 | 107534 | 30930 | 13254 | 1298 |
163327 | 41110 | 148763 | 39710 | 14564 | 1400 |
103101 | 29476 | 90284 | 28222 | 12817 | 1254 |
141384 | 39784 | 126641 | 38350 | 14743 | 1434 |
值得关注的是最后两列,从中我们可以发现,虽然去除空白前后可以让页面体积减小十几K,但是经过压缩后其实只相差1-2K了——大约1-2个数据包。这些节省是否值得我们去这么做?再者,博客园的做法是为每个页面的内容使用正则表达式进行替换,那么它所带来开销又是否值得呢?这就要博客园自己进行profiling了……
最后一提,其实去空白字符并非如此简单一件事情。最简单的例子是:您是否遇到某些HTML编辑器或RSS阅读器,它们会让文章中原本工整的代码变成一行?这就是因为它们武断地去除了所有的空白字符,但是忘了有个HTML标记叫做<pre />……