数字营销 · Web开发 · 基础设施

HTML代码到底该不该压缩

通过实际数据对比 HTML 源码压缩与 Gzip 压缩的效果,分析两者对网站传输体积和性能的影响,并讨论普通网站是否有必要额外压缩 HTML。

在我的插件 Super Static Cache 使用过程中,经常会有人问这样的问题:怎么样让 Super Static Cache 插件支持我的 HTML 压缩插件?

本文这里不讨论具体的技术实现,主要分析一下,现在的网站有没有必要再进行 HTML 代码压缩。

代码压缩压缩的是什么?

HTML 的全称是超文本标记语言,HTML 网页本身是一种文本文件,通过在文件中添加标记符,可以告诉浏览器如何显示其中的内容,包括文字大小、颜色、图片显示等。

这意味着文本文件中的一些字符虽然在源代码中具有意义,但在浏览器最终显示的时候并不会体现出来。HTML 代码压缩,主要就是压缩这些在 HTML 中不参与最终显示的字符,包括空格、制表符、换行符等,一些其它内容,例如 HTML 注释,也可以进行压缩。

有了这个基础,我们挑选网络上的 100 张未经 HTML 压缩的页面进行统计。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib2, re
import matplotlib.pyplot as plt

htmlsp = re.compile(r"[\r\n\t]")

def htmlcompress(html):
html = htmlsp.sub("", html)
return html.replace(" ", " ")

urls = open("urls.txt", "rb")
comdation = list()

while True:
url = urls.readline()

if not url:
break

if not len(url):
continue

try:
content = urllib2.urlopen(url).read()
except:
continue

unlen = len(content)
comlen = len(htmlcompress(content))
comra = 100.0 * (unlen * 1.0 - comlen * 1.0) / unlen

obj = "uncompress:%d byte, compress:%d byte, compressratio:%f%%" % (
unlen, comlen, comra
)

print obj
comdation.append(comra)

plt.ylabel("compressratio")
plt.plot(comdation)
plt.show()

其压缩率分布图如下:

HTML代码压缩率统计

从图中可以看到,压缩率最高的可以达到 20% 以上。那么,是不是就意味着 HTML 很有必要进行压缩?

实际上我们忽略了一个问题:HTML 本身属于文本数据,如果服务器采用合适的压缩算法,它本身就可以获得很高的压缩率。

当时已经有大量网站启用了 Gzip 压缩[1]。那么,如果 HTML 本身已经通过 Gzip 传输,HTML 代码压缩还有多大的意义呢?

下面继续通过程序进行分析:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib2, re
import matplotlib.pyplot as plt
import gzip, StringIO

htmlsp = re.compile(r"[\r\n\t]")

def htmlcompress(html):
html = htmlsp.sub("", html)
return html.replace(" ", "")

def gzipcompress(html):
buf = StringIO.StringIO()

f = gzip.GzipFile(
mode="wb",
fileobj=buf
)

f.write(html)
f.close()

return buf.getvalue()

urls = open("urls.txt", "rb")

unlenlist = list()
comlenlist = list()
gzipcomlenlist = list()
gzipcomhtmllenlist = list()

while True:
url = urls.readline()

if not url:
break

if not len(url):
continue

try:
content = urllib2.urlopen(url).read()
except:
continue

unlen = len(content)
comlen = len(htmlcompress(content))
gzipcomlen = len(gzipcompress(content))
gzipcomhtmllen = len(gzipcompress(htmlcompress(content)))

unlenlist.append(unlen)
comlenlist.append(comlen)
gzipcomlenlist.append(gzipcomlen)
gzipcomhtmllenlist.append(gzipcomhtmllen)

plt.ylabel("HTML Length(byte)")
plt.xlabel("WebSite")

plt.plot(unlenlist, "b")
plt.plot(comlenlist, "r")
plt.plot(gzipcomlenlist, "y")
plt.plot(gzipcomhtmllenlist, "k")

plt.show()

分布图如下:

HTML压缩和Gzip压缩的对比

图中蓝线表示原始网页大小,红线表示 HTML 压缩后的大小,黄线表示 Gzip 压缩原始文件后的大小,黑线表示 Gzip 压缩 HTML 压缩文件后的大小。

可以得出两个结论:

  1. 只有在原始网页文件比较大的时候,HTML 压缩才可能节省一些空间。
  2. 只要服务器开启 Gzip 压缩,HTML 是否进行额外压缩,对最终网页传输体积的影响就比较有限。

所以,我们可以得出一个比较简单的结论:

对于大多数网站来说,单独进行 HTML 代码压缩,对网站性能提升的意义并不大。

当然,把 HTML 压缩之后还可以让源代码变得不那么容易阅读,但随着越来越多的前端开发工具出现,这种作用也越来越有限,反而可能增加调试和维护的成本。

所以,对于普通网站来说,与其花精力做 HTML 压缩,不如优先把精力放在真正影响性能的地方。

当然,这个结论也不是在所有情况下都成立。

当访问量足够大的时候,即使只减少一个字节,也可能带来非常可观的流量成本节省。

以 Google 为例,2013 年 Google 一次宕机事件曾经导致全球互联网流量短时间下降约 40%[2]。同时,当时 Cisco 对 2016 年全球网络流量做出了约 1.3 ZB 的预测[3]。

假设一个非常极端的情况:每 1MB 请求只减少 1 个字节,那么在这种超大规模的流量基础上,累计节省的传输数据量也会非常可观。

所以,HTML 代码压缩并不是完全没有价值,而是需要根据网站的实际规模和成本进行判断。

对于绝大多数普通网站来说,开启 Gzip 等传输层压缩之后,额外进行 HTML 源码压缩的收益已经比较有限。

参考资料

  1. Usage of Gzip Compression for websites
  2. 谷歌宕机5分钟 造成全球互联网流量下降40%
  3. 2016年全球网络流量预测

评论0

欢迎分享你的看法,也欢迎补充不同的实践经验。