nginx gzip压缩html,nginx使用gzip压缩文件

团队文化:进取,分享,快乐,责任!

团队愿景:做最好的产品,打造有影响力的团队!

一个热爱技术,气氛活跃,开放分享的团队,长期招聘架构师,高级java开发工程师,高级前端开发工程师数名,期待你的加入,简历投递:panjian@jd.com

为了提高页面的响应速度,可以从设置 nginx 的 gzip 和缓存这2方面入手,而为ttf,js,css等文件开启 gzip 和缓存能大大减少带宽的消耗.

HTTP 的内容编码机制

Accept-Encoding 和 Content-Encoding 是 HTTP 中用来对[采用何种编码格式传输正文]进行协定的一对头部字段. 它的工作原理是这样:

浏览器发送请求时,通过Accept-Encoding带上自己支持的内容编码格式列表;

服务端从中挑选一种用来对正文进行编码,并通过Content-Encoding响应头指明选定的格式;

浏览器拿到响应正文后,依据Content-Encoding进行解压.

当然,服务端也可以返回未压缩的正文,但这种情况不允许返回Content-Encoding;

这个过程就是HTTP的内容编码机制.

Accept-Encoding,作为请求首部字段,可以一次性指定多种内容编码,比如:

1.gzip

由文件压缩程序gzip(GNU zip)生成的编码格式(RFC1952),采用Lempel-Ziv算法(LZ77)及32位冗余校验(CyclicRedundancyCheck,统称CRC);

文章后面会统一介绍gzip的算法;

2.compress

由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法(LZW);

3.deflate

组合使用zlib格式(RFC1950)及由default压缩算法(RFC1951)生成的编码格式;

4.identity

不执行压缩或者不会变化的默认编码格式.

Content-Encoding作为实体首部字段,采用的内容编码格式和Accept-Encoding是相对应的.

在nginx上添加以下逻辑,用来压缩字体文件,以达到节省网络带宽,提高网站速度的作用.

#字体有很多格式,为匹配字体格式的文件进行压缩设置

#就是拦截这种请求,然后压缩:www.test.com/dist/aabbccddeeffgg.ttf

location~*^/dist/.+\.(eot|ttf|otf|woff|svg)${

#不缓存

expires0;

#增加type对应类型

types{

application/vnd.ms-fontobject eot;

font/ttf ttf;

font/opentype otf;

font/x-woff woff;

image/svg+xml svg;

}

# 开启gzip

gzip  on;

# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩

gzip_min_length1k;

# 设置压缩所需要的缓冲区大小

gzip_buffers416k;

#压缩版本(默认1.1,前端如果是squid2.5请使用1.0)

gzip_http_version1.0;

#压缩等级 1-9 等级越高,压缩效果越好,节约宽带,但CPU消耗大

gzip_comp_level3;

# 进行压缩的文件类型,默认就已经包含text/html。javascript有多种形式。其中的值可以在 mime.types 文件中找到。

gzip_types font/ttf font/opentype font/x-woff image/svg+xml;

# 是否在http header中添加Vary: Accept-Encoding,建议开启

gzip_vary on;

# 禁用IE 6 gzip , 因为IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死

gzip_disable"MSIE [1-6].";

}

测试结果:

f11e2828088da9f632812b7c77117a50.png

用curl测试gzip是否开启成功

curl-I-H"Accept-Encoding: gzip, deflate""http://www.test.com/dist/aabbccddeeffgg.ttf"

gzip未开启:

TP/1.1200OK

Server:JDWS/1.0.0

Date:Tue,21Aug201801:49:24GMT

Content-Length:18520

Connection:close

Last-Modified:Mon,20Aug201809:40:38GMT

Accept-Ranges:bytes

Expires:Tue,21Aug201801:49:24GMT

Cache-Control:max-age=0

gzip开启:

TP/1.1200OK

Server:JDWS/1.0.0

Date:Tue,21Aug201801:48:10GMT

Content-Type:font/ttf

Last-Modified:Fri,10Aug201806:13:07GMT

Connection:close

Vary:Accept-Encoding

Expires:Tue,21Aug201801:48:10GMT

Cache-Control:max-age=0

Content-Encoding:gzip

gzip压缩算法:

gzip是一种数据压缩格式,或者说是一种文件格式,用.gz结尾;

gzip可以极大的加速网站.有时压缩比率高达80%,一般最少都有40%左右;

对于要压缩的文件,使用gzip,主要分为两步:

1.使用LZ77压缩算法进行压缩,得到初始结果;

2.使用Haffman编码对初始结果进行再压缩,得到最终结果.

详细说下这两种算法:

LZ77算法

这个算法是由JacobZiv和AbrahamLempel于1977年提出,所以命名为LZ77.

整体思路:

我们认为是一段内容总会有重复的内容,后面重复的内容可以用两者之间的距离加内容长度联合替换,

而替换后的内容的所占空间一般都会比原内容小,重复越多,压缩完空间就越小.

详细实现过程:

先介绍三个概念:

1.待编码区(字符从这里进来);

2.已编码区(字符从这里出去,也叫缓冲区);

3.滑动窗口(左边是已编码区,右边是待编码区,字符会从右向左依次被读取).

|滑动窗口|

|已编码区|待编码区|

||a   a   b|c  b  b  a  b  c

再看看大概步骤:

1.字符a从待编码区进来,此时a在待编码区的最左边;

2.在待编码区查找从这个a字符在已编码区的最大匹配长度;

3.如果能找到,就输出(偏移量m,最大匹配长度n),滑动窗口向右偏移n个位置;

偏移量m就是待编码区的字符a到已编码区匹配到的字符a的移动距离;

最大匹配长度n就是待编码区有多少连续字符可以在已编码区找到匹配的,这些连续字符的长度;

4.如果找不到,就输出(0,0,a),滑动窗口向右偏移1位;

5.直到待编码区为空,就停止编码,否则继续从2开始循环.

以上面的字符串为例,举个简单易懂的例子:

第一步:a到待编码区的最左边了,在已编码区没有找到匹配的字符,输出(0,0,a), 如下图所示

57364e4da41afb38e146f6af847cd07b.png

滑动窗口准备右移一位,到第二步.

第二步:开始编码,待编码区的第一个字符是a,在已编码区查找匹配字符,找到了; 继续在待编码区读到ab两个字符,在已编码区查找匹配字符,没找到; 所以本次编码待编码区的第一个字符a,输出(1,1); 第一个1代表待编码区的a到已编码区的偏移量,偏移一位,记为1; 第二个1代表本次可编码的长度,因为只有一个a,所以记为1. 如下图所示

be1c8c8605d53671b58f702eb48b4d87.png

滑动窗口准备右移一位,到第三步.

第三步:待编码区第一个字符是b,在已编码区查找匹配字符,没找到; 同第一步,输出(0,0,b). 如下图所示

29463e7a39cf0135e82f9634b90cee44.png

滑动窗口准备右移一位,到第四步.

第四步:待编码区第一个字符是c,在已编码区查找匹配字符,没找到; 同第一步,输出(0,0,c). 如下图所示

5720d0d806e968765b074094c36f8b07.png

滑动窗口准备右移一位,到第五步.

第五步:待编码区第一个字符是b,在已编码区查找匹配字符,找到了; 待编码区前两个字符是bb,在已编码区查找匹配字符,没找到; 所以本次编码待编码区的第一个字符b,输出(2,1). 如下图所示

08b36783d97fb34b3fce60494eb39f5b.png

滑动窗口准备右移一位,到第六步.

第六步:待编码区第一个字符是b,在已编码区查找匹配字符,找到了; 待编码区前两个字符是ba,在已编码区查找匹配字符,没找到; 所以本次编码待编码区的第一个字符b,输出(3,1). 如下图所示

25d403f4e519945e9561915d82ae54e3.png

滑动窗口准备右移一位,到第七步.

第七步:待编码区第一个字符是a,在已编码区查找匹配字符,找到了; 待编码区前两个字符是ab,在已编码区查找匹配字符,找到了; 待编码区前三个字符是abc,在已编码区查找匹配字符,找到了; 这个例子待编码区只有三个字符的长度,实际会很长,就一直找,直到找不到匹配字符为止; 所以本次编码待编码区的前三个字符abc,输出(5,3). 如下图所示

38235eb08d13b41bf6cf7a63b377d83c.png

滑动窗口准备右移三位,到第八步.

第八步:待编码区没有字符了,结束

66030b5c13b86a6c72cb5014ef1f88cd.png

最终结果:(0,0,a)(1,1)(0,0,b)(0,0,c)(2,1)(3,1)(5,3) 通过这个结果反向解码,也能得到原文: aabcbbabc 而且解码比编码还要快很多,主要是因为少了匹配这一步.

Haffman编码

整体思路:

我们知道,普通的编码都是定长的,比如ASCII编码,每个字符编码后的长度都是固定长度,

在解码的时候也就相对简单,只需按照定长将码解开,逐个翻译成对应的字符即可;

而haffman采用的是可变长编码,目的是为了让出现次数多的字符采用更少的长度来存储,

这样就可能会大大加强压缩力度;

haffman建立了树的概念,haffman树是一种二叉树,将所有符号都对应到树的叶子节点上,

每个叶子节点都是可以唯一表示的,都是用若干个0和1组成的;

由于所有的字符最终都会落在叶子节点上,即任何字符的编码都不会是其他字符编码的前缀,

所以在解析的时候,也不会发生混淆的问题,因此haffman编码后的码,也是一种唯一可译码.

详细实现过程:

1.先读所有文件,将所有内容中所有字符出现的次数统计出来做排序;

2.我们将出现少的两个字符作为子节点,可以确定一个父节点,值就是两个子节点的次数和;

3.将上一步的父节点当做一个子节点,再重复执行第二步,直到所有节点全部用完,构成一颗大树;

4.每个数从父节点开始,默认左边的子节点是0,右边的子节点是1,

那么所有的字符对应的子节点都会有唯一的标识了;

5.用这些唯一标识来代替原来的字符,就是编码后的结果;

6.解码的时候,也是先根据所有字符的次数构成那颗大树,然后根据大树找出对应的字符即可.

举个简单易懂的例子: 比如文件的内容是:abbbbccccddde 我们可以统计出: a出现1次; b出现4次; c出现4次; d出现3次; e出现1次;

第一步:找出所有字符出现的次数. 如下图所示

193fbaa5e27732578a1f5c44f83ad526.png

第二步:找出两个最小次数的字符,构成一颗树; a字符和e字符都只出现1次,次数最少,构成一颗树; 产生新的节点,个数为a和e次数的和,即为1+1=2. 如下图所示

5015125e6c825cc250607fb4eb26e00b.png

第三步:再找出剩下的节点中出现次数最小的两个节点; 找出d字符和上一步的新节点,分别一个是3次,一个是2次; 这两个节点继续壮大这颗树,再产生新的节点,次数为3+2=5次. 如下图所示

b6d4a8d240458a9e99ed9efb805bacaa.png

第四步:再从剩下的节点中找出最小的两个,是b和c 构成新的树,父节点是4+4=8 如下图所示

62347467fd1f568de4c1d3d1c6324d67.png

第五步:将最后两个节点合并成一颗大树; 最上面是树的根节点; 最下面是每个字符对应的子节点; 我们默认为:从根节点自上向下看开始计数,往左拐记为0,往右拐记为1; 那么从根节点到下面每个子节点的路径所对应的计数的组合,就是这个字符所要代替的01组合. 如下图所示

c6855df15f761e3610bb01b71fdf2b98.png

最终不难看出: a对应110 b对应00 c对应01 d对应10 e对应111 那么原内容:abbbbccccddde 就可以替换为:1100000000001010101101010111 这个就是压缩后的内容, 那么在解压的时候,再将这些10的组合依次替换成对应的字符即可.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值