web压缩常见方式为gzip,流式压缩,配合以http的Transfer-Encoding为chunked,达到节省带宽,加快页面加载的目的。
brotli是google开源的,基于LZ77无损压缩算法,它最初为woff2字体压缩使用。它有不同的压缩模式,其中就有专门针对woff2的字体压缩模式。它内置一个文本词典,来自google统计的常见英文单词及组合。http请求的Accept-Encoding中简称为br。
brotli的压缩等级范围为1到11,默认为11,而gzip的压缩等级范围为1到9,默认值为6。从网上的一些实验文章结论来看,brotli的level=4跟gzip的level=6,其压缩比差不多,但是有更好的压缩速度,大约快24%左右。
以百度首页为例,页面尺寸为156785字节,结果如下:
gzip cost: 0.004928s, size: 33289
brotli cost: 0.003303s, size: 33850
brotli比gzip快30%,而压缩结果差不太多。
测试代码如下,均采用python封装,均采用流式压缩,以模拟真实的web处理流程:
gzip测试代码:
file_name = 'baidu.html'
t1 = time()
_gzip_value = BytesIO()
_gzip_file = gzip.GzipFile(mode="w", fileobj=_gzip_value, compresslevel=6)
chunks = []
with open(file_name, 'rb') as f:
while True:
data = f.read(64 * 1024)
if not data:
break
_gzip_file.write(data)
_gzip_file.flush()
chunks.append(_gzip_value.getvalue())
_gzip_value.truncate(0)
_gzip_value.seek(0)
_gzip_file.close()
chunks.append(_gzip_value.getvalue())
res = b''.join(chunks)
t2 = time()
print('gzip cost: %f, size: %d' % ((t2-t1), len(res)))
brotli测试代码:
t1 = time()
chunks = []
_brotli = brotli.Compressor(quality=4)
with open(file_name, 'rb') as f:
while True:
data = f.read(64 * 1024)
if not data:
break
ch = _brotli.process(data)
if ch:
chunks.append(ch)
chunks.append(_brotli.flush())
chunks.append(_brotli.finish())
res = b''.join(chunks)
t2 = time()
print('brotli cost: %f, size: %d' % ((t2-t1), len(res)))
越小的文本内容压缩,brotli越有优势。有趣的是,经过测试,就算不是可读文本,压缩二进制文件,brotli也比gzip快得多。同时,还发现阿里云CDN默认并未开启压缩功能,需要在CDN性能优化配置里手动开启gzip和brotli压缩,这着实让我惊讶。