Hello World
Spiga

真有必要去除HTML中的空白字符吗?

2009-12-07 17:59 by 老赵, 11133 visits

刚才有朋友在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 />……

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

54 条回复

  1. Jeff Wong
    *.*.*.*
    链接

    Jeff Wong 2009-12-07 18:15:00

  2. 五味果
    *.*.*.*
    链接

    五味果 2009-12-07 18:20:00

    发布后对页面进行一次压缩,去掉注释,无谓的空格。

  3. Gray Zhang
    *.*.*.*
    链接

    Gray Zhang 2009-12-07 18:28:00

    对我而言去空格的最大作用是防止空格在IE中渲染出来,同时换行也会渲染为空格,导致很多布局上的错误,有时1像素就会扩乱整个页面的结构

  4. 老赵
    admin
    链接

    老赵 2009-12-07 18:28:00

    @五味果
    静态压缩,可行,虽然效果也就1、2K罢,如果觉得麻烦,不做也行。
    注释这东西,如asp.net里的,只要使用<%-- --%>,生成的页面中自然就没有了。

  5. 老赵
    admin
    链接

    老赵 2009-12-07 18:30:00

    @Gray Zhang
    那就不应该是在后期去除空格了,而是应该在编写过程中就避免,例如少换点行之类的,呵呵。

  6. 余魁
    *.*.*.*
    链接

    余魁 2009-12-07 18:36:00

    想过这个问题!要是不用GZip压缩会提升性能吗?我看bing首页的代码就没有空格了。

  7. Kaelzhang[未注册用户]
    *.*.*.*
    链接

    Kaelzhang[未注册用户] 2009-12-07 18:37:00

    程序上传至beta时,对css,js,html压缩一次。
    压缩工具有简单的编译能力最好

  8. Ryan Gene
    *.*.*.*
    链接

    Ryan Gene 2009-12-07 18:39:00

    浏览器对于html tag之间有无whitespace处理是有差别的,这点要注意下

  9. Kevin  Yang[未注册用户]
    *.*.*.*
    链接

    Kevin Yang[未注册用户] 2009-12-07 18:41:00

    对于大流量的网站来说,1~2K还是能够很明显的提高整个系统的承载能力的。像微软首页也是压缩过的。

  10. 找图标
    *.*.*.*
    链接

    找图标 2009-12-07 18:43:00

    对性能要求非常苛刻的页面可以考虑这样做。

  11. javascript[未注册用户]
    *.*.*.*
    链接

    javascript[未注册用户] 2009-12-07 18:44:00

    既然采用了gzip,还去除空白字符就纯属脱裤子放屁,虽然可以保护裤子面料,但一点也不值得。
    唯一的例外情形是:需将gzip之后缓存起来,且在缓存生命期内,访问量巨大。

  12. 老赵
    admin
    链接

    老赵 2009-12-07 18:45:00

    @Kevin Yang
    你确定1-2K就能明显提高系统承载能力?这已经远不是性能瓶颈了吧。
    微软的首页压缩自有它的道理,而且即便压缩也有不同的方式,例如动态压缩,静态压缩等等。
    压不压缩,是得失之间的权衡,不是看谁压了,那么我也非要压不可。

  13. 老赵
    admin
    链接

    老赵 2009-12-07 18:47:00

    找图标:对性能要求非常苛刻的页面可以考虑这样做。


    还是那句话,如果没有针对性能瓶颈/关键之处进行优化基本是徒劳的。
    那么什么时候这些东西会成为性能瓶颈呢?等真是了再说吧。
    或者,已经确定不会带来什么麻烦的情况下,可以一用——例如打开gzip压缩便是此类。

  14. Gray Zhang
    *.*.*.*
    链接

    Gray Zhang 2009-12-07 18:47:00

    @Jeffrey Zhao
    唉,VS的自支格式化一直给我加上空格,而且有时很多span写在一起不换行也不美观啊,只能折中了

  15. 飞笑
    *.*.*.*
    链接

    飞笑 2009-12-07 18:48:00

    在访问高潮的时候,某一个小段时间内(比如10秒),博客园的访问量可能达到了5000PV,那么1k * 5000 = 5M,或许,是值得的。

  16. Keep Walking
    *.*.*.*
    链接

    Keep Walking 2009-12-07 18:49:00

    很好测试啊,我看些php开源框架也没有这样做的,虽然他们想要压缩空白字符的话,是很容易的一件事情,php使用的缓存池ob_getcontent的时候直接可以从内容过滤后flash到客户端,但是他们没有这样做。

  17. Keep Walking
    *.*.*.*
    链接

    Keep Walking 2009-12-07 18:54:00

    一般是不对动态资源进行压缩的,看了一下博客园对动态内容进行了压缩,但是不知道cpu消耗怎样

  18. 老赵
    admin
    链接

    老赵 2009-12-07 18:55:00

    @飞笑
    我不信博客园会有那么高潮,也不信博客园抗得住每秒500PV,呵呵。
    其实博客园的前端性能还有许多值得优化的地方,去空白(还是动态去除)有些不着要领啊。

  19. 老赵
    admin
    链接

    老赵 2009-12-07 18:56:00

    @Keep Walking
    根据我的经验,Web Server这种本来CPU就不需要多少的地方,动态gzip一下很合算,最多也就10-20%的CPU。

  20. Keep Walking
    *.*.*.*
    链接

    Keep Walking 2009-12-07 18:58:00

    @Jeffrey Zhao
    谢谢
    10-20%的还是很值得啊,看来我有必要在我的网站上尝试尝试

  21. Keep Walking
    *.*.*.*
    链接

    Keep Walking 2009-12-07 19:01:00

    @Jeffrey Zhao
    我觉得博客园最需要优化的地方就是将博客园首页静态化,每十分钟生成一次

  22. Anders Liu
    *.*.*.*
    链接

    Anders Liu 2009-12-07 19:03:00

    我觉得应该把节省的百分比列出来。现在的问题不是节省了1k还是10k的流量,而是节省了百分之多少。

    《高性能网站建设指南》(High Performance Web Site,就是那著名的14个原则)中,有提到用gzip压缩页面,也有提到精简css和js,但没有提到消除HTML或代码中的空白字符,这是不是也是一种隐喻呢?

  23. 老赵
    admin
    链接

    老赵 2009-12-07 19:06:00

    @Keep Walking
    我倒觉得博客园现在可以放过首页,性能已经很高了,静态页能带来多少性能提升也值得打个问号。

  24. 老赵
    admin
    链接

    老赵 2009-12-07 19:08:00

    @Anders Liu
    唉,其实我比较担心博客园是否有合适的监控机制,如果有的话应该也不会没意识到memcached挂了。
    话说我有点奇怪,为啥memcached挂了却只有发评论受影响,其他浏览很正常啊。

  25. Galactica
    *.*.*.*
    链接

    Galactica 2009-12-07 19:17:00

    用柱状图表示,直观的多.

  26. 飞笑
    *.*.*.*
    链接

    飞笑 2009-12-07 19:22:00

    @Jeffrey Zhao
    我是从这里看到的:
    http://www.cnblogs.com/dudu/archive/2009/11/10/1600062.html
    或许偶尔能达到。

    刚刚略看了一下本页的源代码,没细研究外部引用的js/css等,单看页内源码,除了中间有一大片inline的js以及从头至尾好多地方有js之外,基本山还中规中矩。本页没有太多特别的js效果,估计也不会有太复杂的js逻辑,而且非自定义的东西比较少,所以,我感觉前端的优化工作可能大部分都是这种细小的一点一滴的工作了。所以,他们大概是这个思维:有足够的人力的话,就搞一搞,优先级不是太高,但是终究得做。呵呵。

  27. 老赵
    admin
    链接

    老赵 2009-12-07 19:24:00

    @飞笑
    那片文章只是打开一个瓶颈,不是说pv就达到这么多了,连接不等于pv。请求一张页面可能就发起5、6个连接了,而且每个连接可能持续好几秒……
    前端优化也是有优先顺序的,需要profiling的。

  28. 飞笑
    *.*.*.*
    链接

    飞笑 2009-12-07 19:28:00

    Jeffrey Zhao:
    @飞笑
    那片文章只是打开一个瓶颈,不是说pv就达到这么多了,连接不等于pv。请求一张页面可能就发起5、6个连接了,而且每个连接可能持续好几秒……
    前端优化也是有优先顺序的,需要profiling的。



    我错了,老想着PV==连接。

  29. Keep Walking
    *.*.*.*
    链接

    Keep Walking 2009-12-07 19:49:00

    @Jeffrey Zhao
    如果做了页面缓存,倒是没有必要再静态化
    可以让开发团队在服务器上用AB压压静态页和缓存动态页的吞吐对比

  30. 深山老林
    *.*.*.*
    链接

    深山老林 2009-12-07 20:09:00

    同感。

  31. canbeing
    *.*.*.*
    链接

    canbeing 2009-12-07 21:00:00

    喜欢老赵的用数字说话和刨根究底的探索精神。
    偶也觉得没有必要去空格

  32. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-12-07 21:13:00

    Kevin Yang:对于大流量的网站来说,1~2K还是能够很明显的提高整个系统的承载能力的。像微软首页也是压缩过的。



    很多时候不一定是Web服务器压缩的。。。。。
    也许CDN也有自己的算盘。。。。

  33. san.
    *.*.*.*
    链接

    san. 2009-12-07 21:37:00

    研究问题都那么透彻!!!赞

  34. 郑州--飞猫
    *.*.*.*
    链接

    郑州--飞猫 2009-12-07 22:49:00

    在这看解决问题的方法,受益匪浅~

  35. leeolevis
    *.*.*.*
    链接

    leeolevis 2009-12-08 08:36:00

    我觉得没必要对代码那么苛刻,空格确实可以增加美观度:)
    譬如老赵说的<span>。现在开发程序都不喜欢页面有任何.Net生成的代码,当然实现方法有很多,配置,仿MVC,或者现在真正的asp.net MVC。但是对比一下国外的技术网站,查看他们源文件都会发现有着大量的.Net生成的代码,他们不会在意那些.Net自动生成的代码和使用大量的服务器控件,在意的只是客服体验和服务,感觉他们真是把winfrom发挥到极致了。呵呵,跑偏了:)
    http://www.cnblogs.com/JeffreyZhao/archive/2007/12/22/Experience-for-Asp-dot-net-and-WebForms.html

  36. 极杜空间
    *.*.*.*
    链接

    极杜空间 2009-12-08 09:31:00

    Jeffrey Zhao:
    @Gray Zhang
    那就不应该是在后期去除空格了,而是应该在编写过程中就避免,例如少换点行之类的,呵呵。


    只要不影响IE渲染的时候,我觉得代码编写的过程中换行与空格是必须的,有利于代码的可读性。最终发布出来,再去考虑下压缩代码吧。

  37. 懒得登录[未注册用户]
    *.*.*.*
    链接

    懒得登录[未注册用户] 2009-12-08 16:49:00

    我记得Visual Studio的HTML编辑器是可以进行很详细的设置的,虽然第一次有点麻烦,但值得去做。

  38. 韦恩卑鄙 alias:v-zhewg
    *.*.*.*
    链接

    韦恩卑鄙 alias:v-zhewg 2009-12-08 21:21:00

    打听说gzip那天开始 我就忘记删除空格是干什么用的了

  39. JimLiu
    *.*.*.*
    链接

    JimLiu 2009-12-09 12:06:00

    我很无语
    觉得每个网页1~2K会造成性能(明显)下降的朋友可以做做这个算盘:
    打算平均每个网页60K,1~2K只是3%而已,这可真是堪比“九牛一毛”了。但是正则表达式替换字符串那可是不小的开销哦~不做完整的测试又怎么能知道二者比起来是哪个多呢?
    放远一点看,少一个该有的缓存,或者访问数据库的时候少一个不起眼又有效的查询优化,比起这种犄角旮旯的斤斤计较,哪个更容易造成系统性能下降?

  40. 问天
    *.*.*.*
    链接

    问天 2009-12-11 04:54:00

    rails在很多年前就在模板中内置了一个“-”函数,类似:
    <%for 1 to 10 -%>
    <p></p>
    <div></div>
    <%next%>

    模板输出的时候自动把多余的空格、换行符干掉。

    在asp.net里面要实现也很容易,写个类基类继承UI.Page。overwrite render方法,用个正则把所有多余空格、换行干掉。

    在我开发的一个手机wap站中,便采用了这个方法。

    html中的空格可以去去除,但不是一定要用修改自己模板文件的方式去去除。

  41. Kevin Dai
    *.*.*.*
    链接

    Kevin Dai 2009-12-11 11:44:00

    文章最后一段倒是给大家提了个醒。

  42. 问天
    *.*.*.*
    链接

    问天 2009-12-11 13:22:00

    囧,我回错贴了。

  43. YJJ
    *.*.*.*
    链接

    YJJ 2009-12-12 09:46:00

    Gray Zhang:对我而言去空格的最大作用是防止空格在IE中渲染出来,同时换行也会渲染为空格,导致很多布局上的错误,有时1像素就会扩乱整个页面的结构


    请问除了去掉空格
    如何“防止空格在IE中渲染出来”
    因为有时候在vs2008 按 Ctrl+K+D 自动格式化html后
    显示出来的布局会多出一些空行 空格之类的东西,挺烦人的
    你不格式化吧,代码又太乱,不好阅读
    请高人指教!

  44. 老赵
    admin
    链接

    老赵 2009-12-12 12:28:00

    @YJJ
    对于HTML,我从来不用VS自动格式化,都是自己控制格式的。

  45. yunle[未注册用户]
    *.*.*.*
    链接

    yunle[未注册用户] 2009-12-14 13:28:00

    随便用哪个浏览器都显示不正常了 你的blog~~~

  46. 老赵
    admin
    链接

    老赵 2009-12-14 13:33:00

    @yunle
    其实IE是好的,呵呵。:)

  47. 五味果
    *.*.*.*
    链接

    五味果 2009-12-16 10:33:00

    其实最好的解决方案是微软vs团队能对vs网站的发布机制做下改进,发布时,增加一个复选框,是否对html页面进行压缩,选择后发布网站时,自动去除注释,无谓的换行,空格等,压缩后的页面代码就像百度谷歌那样的html代码,经过高度压缩了的。
    这样的话有三个好处:
    1:开发时不用考虑html代码后边的压缩,可以随意格式化页面代码。加注释等等。
    2:对html代码也是一种保护,没有排版注释的html代码别人想复制改动就需要多花功夫。
    3:有效的减少了传输量,这样压缩后的html代码一般能减少30%到60%的大小。
    vs的网站发布机制还有很大改进空间。

  48. 老赵
    admin
    链接

    老赵 2009-12-16 10:55:00

    @五味果
    压缩后的html代码能减少30%到60%的大小?我的文章不是已经给出实验数据了吗?
    注释本来就是没的,只要用<%-- -- %>就行了,而HTML的排版,随便找个工具就能格式化了。去空白又不是混淆,HTML没法混淆的。

  49. 五味果
    *.*.*.*
    链接

    五味果 2009-12-16 11:53:00

    @Jeffrey Zhao
    我指的是没有gzip压缩之前的大小。
    以你这篇文章页面大小为例:
    直接把源代码文件存成文本文件,大小是160kb,经过简单的去空格去换行后压缩之后大小是:128k:
    去除html注释后是:115k;从源头上减少了代码大小。
    从源头上减少一些无谓的数据。html里写的注释不少。
    美工人员加注释一般用的是<!-- -->
    我们发送到客户端的html源代码应该是给电脑看的,而不是给人看的。
    gzip压缩应该是精简后的html代码,而不是直接GZIp压缩了事。

    仅是探讨。

  50. 老赵
    admin
    链接

    老赵 2009-12-16 12:11:00

    @五味果
    我都是让美工直接加<%-- --%>注释的,呵呵。去空白有那么多?那为什么我的测试没有那么明显。
    既然要gzip,去空白的效果就没有了。我说不用去空白,就是因为gzip后大断空白不占用什么空间。
    html的确是给电脑看的,空白不会影响电脑啊,所以我们就不用费神去空白了,呵呵,我就是这个意思。

  51. benfeng
    *.*.*.*
    链接

    benfeng 2009-12-17 16:46:00

    哈哈,<pre />!!
    一针见血!

  52. 飘扬
    *.*.*.*
    链接

    飘扬 2010-02-22 21:00:00

    能省一点是一点。。。。。不过从这2-3K来看。加载速度也就只相差那么多的。到了万分不得已的时候再考虑这么方法。。。。。不过话说话回其实删除了空格对代码浏览其实也没什么影响的。毕竟还有一些工具可以自动格式化代码的。。。还是不删了。。如果都删了那margin这样的属性也不太多了些~~~~~~

  53. youyo
    106.187.102.*
    链接

    youyo 2012-12-30 01:23:44

    hi,我以为,根据gzip的压缩方法,是否去除html内的字符真的影响不大。 如果没有gzip,还是有影响的,一个空格就是一个字符的传输量 现在几乎所有的server都是能做gzip的。 问题来了:并不是所有的客户端(浏览器)都能告诉服务器它支持gzip(如:代理重写了http头、移动cnwap去掉了2g用户浏览器的http头的部分及全部user agent) 老赵的观点呢?

  54. 老赵
    admin
    链接

    老赵 2013-01-01 22:31:47

    @youyo

    自己决定吧,比如有些大站,省一个字节是一个,甚至连html标签的close tag都去掉。至于gzip,服务器端自然还是根据request header来给。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我