gzip和deflate在web应用的区别
2018-09-07 11:08:12 阿炯

gzip是一种数据格式,deflate/inflate是压缩算法,是huffman编码的一种加强。默认且目前仅使用deflate算法压缩data部分,deflate与gzip解压的代码几乎相同,可以合成一块代码。

区别仅有:

deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比 inflateInit()多一个参数: -MAX_WBITS,表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节。使用inflateInit2时要求zlib库忽略zlib header。在zlib手册中要求windowBits为8..15,但是实际上其它范围的数据有特殊作用,见zlib.h中的注释,如负数表示raw deflate。

Apache的deflate变种可能也没有zlib header,需要添加假头后处理。即MS的错误deflate (raw deflate),zlib头第1字节一般是0x78,第2字节与第一字节合起来的双字节应能被31整除,详见rfc1950。例如Firefox的zlib假头为0x7801。

deflate 是最基础的算法,gzip 在 deflate 的 raw data 前增加了 10 个字节的 gzheader,尾部添加了 8 个字节的校验字节(可选 crc32 和 adler32) 和长度标识字节。

Deflate不仅能支持很好的适配现在已有的系统,而且它比较简单快速的编解码。因此很多无损数据压缩都采用Deflate方法实现的。2013年,谷歌发布Zopfli,改进算法不仅兼容Deflate格式,而且支持稠密压缩。现在Zopfli逐渐广泛被接受,有人开始提出目前应该从Deflate算法向更加先进的算法转变。

deflate 是最基础的算法,gzip在deflate的rawdata前增加了10个字节的 gzheader,尾部添加了8个字节的校验字节(可选 crc32 和 adler32) 和长度标识字节。

zlib库是一个C++常用的解压zip文件的库,提供了各种各样的接口以供调用。其中,deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比 inflateInit()多一个参数: -MAX_WBITS,表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节,使用inflateInit2时要求zlib库忽略zlib header。

zlib提供了很多接口,在这些复杂的操作之上封装了最简单的两个接口:compress和uncompress,我们一般直接调用就可以了。


gzip和deflate在web应用方面的区别

HTTP定义了一种机制,一个Web客户机和Web服务器同意一压缩方案可以用来发送内容,这是使用接受编码和内容编码标头完成。有两种常用的HTTP压缩:DEFLATE和GZIP。

DEFLATE是一个无专利的压缩算法,它可以实现无损数据压缩,有众多开源的实现算法。GZIP是使用DEFLATE进行压缩数据的另一个压缩库。

gzip和deflate的几点区别(以Apache服务器为例)

Apache服务器通过mod_gzip和mod_deflate这两个地方来开启网站的GZip压缩,不管使用mod_gzip 还是mod_deflate,此处返回的信息都一样,因为它们都是实现的gzip压缩方式。这里主要说说它们之间的几点区别,HTTP定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码。

Content-Encoding header 就用这些标准化的代号来说明编码时使用的算法

Content-Encoding值

gzip  表明实体采用GNU zip编码

compress 表明实体采用Unix的文件压缩程序

deflate  表明实体是用zlib的格式压缩的

identity  表明没有对实体进行编码。当没有Content-Encoding header时, 就默认为这种情况

gzip, compress, 以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。其中gzip通常效率最高,使用最为广泛。


第一、Apache Web服务器版本差异

Apache 1.x系列没有内建网页压缩技术,所以才去用额外的第三方mod_gzip 模块来执行压缩。而Apache 2.x官方在开发的时候,就把网页压缩考虑进去,内建了mod_deflate 这个模块,用以取代mod_gzip。虽然两者都是使用的Gzip压缩算法,它们的运作原理是类似的。

第二、压缩质量

mod_deflate压缩速度略快而mod_gzip 的压缩比略高。一般默认情况下,mod_gzip会比mod_deflate多出4%~6%的压缩量。Gzip压缩是在一个文本文件中找出类似的字符串,并临时替换他们,使整个文件变小。这种形式的压缩对Web来说非常适合,因为HTML和CSS文件通常包含大量的重复的字符串,例如空格,标签。

第三、对服务器资源的占用

一般来说mod_gzip 对服务器CPU的占用要高一些。mod_deflate 是专门为确保服务器的性能而使用的一个压缩模块,mod_deflate 需要较少的资源来压缩文件。这意味着在高流量的服务器,使用mod_deflate 可能会比mod_gzip 加载速度更快。

简而言之,如果你的网站,每天不到1000独立访客,想要加快网页的加载速度,就使用mod_gzip。虽然会额外耗费一些服务器资源但也是值得的。如果你的网站每天超过1000独立访客,并且使用的是共享的虚拟主机,所分配系统资源有限的话,使用mod_deflate 将会是更好的选择。

GZIP,好像是一个不透明的或原子的功能。事实上,HTTP定义了一种机制,一个Web客户机和Web服务器同意一压缩方案可以用来发送内容,这由使用Accept-Encoding和Content-Encoding标头完成。有两种常用的HTTP压缩:DEFLATE和GZIP。

DEFLATE是一个无专利的压缩算法,它可以实现无损数据压缩,有众多开源的实现算法。该标准的实施库大多数人用的是zlib的。zlib库提供用于压缩和解压缩使用DEFLATE/INFLATE的数据。zlib库还提供了一种数据格式,混淆的命名ZLIB,它包装DEFLATE压缩数据,具有报头和校验和。

GZIP是使用DEFLATE进行压缩数据的另一个压缩库。事实上,GZIP的大多数实现实际使用zlib库的内部进行DEFLATE/INFLATE压缩操作。GZIP产生其自己的数据格式,混淆的命名GZIP,它包装DEFLATE压缩数据,具有报头和校验和。

早期浏览器对DEFLATE压缩描述混乱

HTTP/1.1 RFC(超文本传输协议HTTP/1.1版)在为Accept-Encoding和Content-Encoding标头描述允许的压缩方案时做得不好,它定义了Content-Encoding:gzip,该响应体由使用GZIP数据格式(GZIP标头,压缩数据,和校验和)组成。它还定义 Content-Encoding:DEFLATE,但尽管它的原来名字,这并不意味着响应体是DEFLATE压缩数据的原始块。根据RFC-2616,DEFLATE和Content-Encoding:DEFLATE,实际上意味着响应体是由zlib的格式(zlib的头,压缩数据和校验)组成的。

这种“DEFLATE的标识并不意味着原始DEFLATE压缩数据”的想法是相当混乱的。早期版本的Microsoft的IIS Web服务器被编程为返回原始DEFLATE压缩数据的Accept-Encoding:deflate要求,而不是一个zlib的格式的响应。而在与Content-Encoding时期望的响应自然版本的Internet Explorer:DEFLATE标头有原始DEFLATE响应主体。

Mark Adler,zlib的作者之一,介绍说:早期的微软服务器会错误地提供“Deflate”的原始压缩(例如RFC1951的数据没有RFC1950的zlib包装)。这导致的问题是,浏览器不得不去试一下两种方式,在最后它只是使用更可靠的GZIP。

现在浏览器对DEFLATE压缩处理不好

如Mark所说,浏览器收到Content-Encoding后,压缩必须处理两种可能的情况:响应主体是原始DEFLATE数据,或响应主体是zlib包装过的DEFLATE响应。那么,现代浏览器处理DEFLATE或zlib包装过的DEFLATE响应效果有多好?Verve工作室测试了一个庞大的浏览器数量,结果并不好。发送原始DEFLATE数据不是一个好主意,正如马克说,“[它]只使用更可靠的GZIP。”

还应该注意的是,所有支持DEFLATE的浏览器都支持GZIP,但不是所有支持GZip的浏览器都支持DEFLATE。有些浏览器,如Android,在它们的Accept-Encoding请求头不包含deflate压缩。由于你不得不配置你的Web服务器使用GZIP,你还不如避免Content-Encoding: deflate。

禁用DEFLATE

Apache处理所有HTTP压缩的模块是mod_deflate模块。尽管它的名字,mod_deflate模块根本不支持deflate。要得到一个发送原始DEFLATE或zlib包装过的DEFLATE的Apache2版本是不可能。Nginx的,如Apache,不支持deflate的,它只会发送gzip压缩的响应,发送Accept-Encoding:deflate请求头将导致未压缩的响应。

如果你的Web服务器发送压缩的DEFLATE内容,无论免费还是商业的产品都具有内置的检测:“过时的压缩格式”。


同类的HTTP压缩算法还有数据压缩算法-Brotli