nginx系列之gzip模块的用法和测评

1、前言

gzip在*nix系统中是个压缩命令,用于把文件压缩成.gz后缀的文件,以减小磁盘占用空间。与之相对应的是命令gunzip,用于解压缩用gzip方法压缩的文件。nginx每天会对当天的访问日志进行压缩,通常在其日志文件目录下也可看到一大堆的access.log-yyyymmdd.gz文件。

nginx有个gzip模块,用于对输出到客户端的内容进行压缩,以减小传输文件体积,减少对网络带宽的占用。在Web应用中通常启用gzip压缩,用来缩短响应时间,提升用户体验。当然,服务器端要压缩,客户端必须解压缩,这都将占用cpu时间。不过,由于传输内容减小了,传输过程中,各网卡、路由器、交换机对数据包的处理时间也会缩短。gzip压缩是就在这里赢得了时间。

2、指令说明

gzip压缩功能要启用,必须满足以下几个条件:

  • 客户端发送的HTTP报头必须含有 “Accept-Encoding” 字段,且其值包含 “gzip” 这个压缩类型。一般浏览器都会发 “Accept-Encoding:gzip, deflate, sdch” 这样的报头。

  • 服务器做响应的配置,以nginx为例,示例配置如下:

# 对static目录下js、css、jpg、jpeg、png、gif后缀的文件启用gzip压缩功能
location ~ /static/(.+)\.(js|css|jpg|jpeg|png|gif) {
    gzip on; # 启用gzip压缩,默认是off,不启用
    # 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
    gzip_types application/javascript text/css image/jpeg image/png image/gif;
    gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
    gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
    gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
}

如果服务器启用了gzip压缩,那么响应头会包含 Content-Encoding:gzip, 客户端根据这个来判断服务器返回的内容是否真正为gzip压缩过的内容。

3、对各文件的压缩比率测试

为方便对文件批量测试,写了个php小程序。

该程序处理的服务器返回的传输类型为分块传输,即带 “Transfer-Encoding:chunked” HTTP响应头。

function testGzip($host, $uri) {
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_connect($socket, '127.0.0.1', 80);

    $request = "GET $uri HTTP/1.1\r\n";
    $request .= "Host: $host\r\n";
    $request .= "Accept-Encoding: gzip\r\n";
    $request .= "Connection: Keep-Alive\r\n\r\n";

    socket_write($socket, $request, strlen($request));

    $headers = [];
    while (($line = socket_read($socket, 1024, PHP_NORMAL_READ))) {
        socket_read($socket, 1, PHP_BINARY_READ);
        if ($line == "\r") {
            break;
        }
        $headers[] = rtrim($line, "\r");
    }

    $totalSize = 0;
    $chunkSizeList = [];
    $data = "";

    while (true) {
        $lenx = rtrim(socket_read($socket, 1024, PHP_NORMAL_READ), "\r");

        socket_read($socket, 1, PHP_BINARY_READ);
        $len =  hexdec($lenx);

        if ($len == 0) {
            socket_read($socket, 2, PHP_BINARY_READ);
            break;
        } else {
            //echo 'len=', $len, PHP_EOL;
        }

        $chunkSizeList[] = $len;
        $totalSize += $len;

        $data .= socket_read($socket, $len, PHP_BINARY_READ);
        socket_read($socket, 2, PHP_BINARY_READ);
        //usleep(10000);
    }

    socket_close($socket);

    $decodedData = gzdecode($data);
    #echo $decodedData;
    return [$headers, $chunkSizeList, $totalSize, strlen($decodedData)];
}

function batchGzipTest($host, $basePath, $files) {
    $stats = [];

    foreach ($files as $jsFile) {
        $stats[$jsFile] = testGzip($host, $basePath . $jsFile);
    }

    echo "|文件名|初始大小|压缩后大小|压缩比率|", PHP_EOL;
    echo "|------|:-----|:-----|:-----|", PHP_EOL;
    foreach($stats as $jsFile => $v) {
        echo "|", $jsFile, "|", $v[3], "|", $v[2], "|", sprintf("%.2f", ($v[3]-$v[2])/$v[3]*100), "%", "|", PHP_EOL;
    }
}

使用示例:

$host = 'invo.com';

$jsPath = '/static/js/';

$jsFiles = [
    'arttemplate.js', 
    'bootstrap.min.js', 
    'fastclick.min.js', 
    'jquery220.min.js', 
    'moment.min.js',
    'vue.js',
];

batchGzipTest($host, $jsPath, $jsFiles);
3.1 js文件压缩比率测试

对常用的6个js文件做了测试,结果如下:

文件名初始大小压缩后大小压缩比率
arttemplate.js4449225749.27%
bootstrap.min.js368681180467.98%
fastclick.min.js8776312464.40%
jquery220.min.js855893494259.17%
moment.min.js407371583861.12%
vue.js2227777515766.26%

最小49.27%,最大67.98%,还算不错!!

3.2 css文件压缩比率测试

对5个css文件进行测试:

文件名初始大小压缩后大小压缩比率
bootstrap.min.css1212602519879.22%
citheme.css2486118652.29%
datepicker3.css33745386788.54%
mui.min.css775571618379.13%
slider.css8486174579.44%

最小52.29%,最大88.64%,相当可以!!

3.3 图片文件压缩比率测试

3个png文件,2个jpg文件。

文件名初始大小压缩后大小压缩比率
1.png16953168820.42%
2.png1170101168750.12%
3.png66492627715.60%
4.jpg7757027719010.49%
5.jpg6208886183910.40%

没什么效果,令人失望!!估计是因为png、jpeg这些格式的图片已经是压缩过了的缘故。

3.4 html文件压缩比率测试

随机对5个html文件进行测试。

文件名初始大小压缩后大小压缩比率
genindex.html1160251776984.69%
index.html53112872683.57%
search.html33589649580.66%
license.html35035728579.21%
DCO.html35168725879.36%

效果比css文件的还要好!!

总结:gzip压缩对文本文件压缩效果非常好(40%~80%),而对图片文件效果甚微。实际应用中可以考虑对js、html、css格式的文件开启gzip压缩。估计json也是不错的,读者有兴趣可以自己去测试下。

4、后记

这篇文章快写完时,MarkDown竟然出问题了,说要重新加载,结果内容全没了。多么痛的领悟!只得收拾残碎的记忆又重新写了一遍。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值