http请求压缩可减少宽带,提升终端加载速度。像http服务自带的压缩是实时的,虽然可通过缓存减少重复请求压缩次数,实际还是不能有效减少重复压缩相同请求,特别是较大的静态文件。
http压缩协议
HTTP 协议中的数据压缩 - HTTP | MDN (mozilla.org)
浏览器会在每个请求中携带 Accept-Encoding 请求头信息,用于标识支持接收的响应数据体编码格式,比如:

http服务器就会选择其中一种编码格式进行返回响应数据体,通过响应头信息 content-encoding 标识,比如:

浏览器获取到支持的响应编码格式后进行解码处理,然后再响应给请求处理(所有浏览器请求)。
nginx 压缩配置
模块ngx_http_gzip_module (nginx.org)
nginx常用压缩配置是通过gzip模块完成的,配置相对简单,常用配置如下:
# 压缩开关 on 或 off
gzip on;
# 打开静态压缩,会尝试响应 $request_filename.gz 预压缩文件如果存在直接返回,不存在会尝试 $request_filename 文件并返回
gzip_static on;
# 最少压缩响应体长度,过小的文件压缩意义不大
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
# 指定压缩响应类型,默认:text/html,如果要全部压缩可使用 *
gzip_types text/plain application/xml;
# 压缩级别: 1~9 级别越大压缩率越高同时CPU开销越大
gzip_comp_level 9;
# 匹配User-Agent头信息包含内容的请求不执行压缩的处理
gzip_disable "MSIE [1-6]\.";
# 开启响应头信息 Vary: Accept-Encoding 代理时使用
gzip_vary on;注意:不同的静态文件压缩率不一样,一般文本类文件压缩率会高些(比如:html、css、js等文件),像图片、音频、视频类压缩率低些。对于压缩率低的文件不建议配置压缩。
预压缩静态文件
nginx非静态压缩是实时的,并且不会缓存前面的压缩结果(缓存由终端浏览器处理),特别是压缩一个大文件会占用较多的CPU,不利于服务器性能利用。
提前将要请求的静态文件进行压缩(压缩文件名是原文件名加 .gz 后缀,且目录不变),然后通过配置请nginx响应出去即可拦截nginx实时压缩又能实现http压缩功能会大大减少nginx压缩开销。
nginx提供了静态压缩功能,即会尝试请求静态文件的压缩文件,比如: index.html 会尝试请求 index.html.gz 文件,当index.html.gz文件存在则直接按压缩模式响应,否则实时压缩index.html文件再返回
预压缩脚本
预压缩脚本代码:保存文件 gzip.php
<?php
if (!extension_loaded('zlib')) {
die("请安装 zlib 扩展");
}
if ($argc < 2) {
die("
批量压缩目录内所有文件,压缩成gzip格式
命令:
php {$argv[0]} source-dir [target-dir]
参数:
source-dir 要压缩的目录
说明:
此脚本用来快速预压缩文件,用于静态压缩http请求静态文件
");
}
$dir = $argv[1];
if (!is_dir($dir)) {
die('目录不存在:' . $dir);
}
$sourceDir = realpath($dir) . '/';
$count = 0;
foreach (forFile($sourceDir) as $file) {
$targetFile = $sourceDir . $file . '.gz';
if (file_exists($targetFile)) {
unlink($targetFile);
}
$gzip = gzopen($targetFile, 'wb9');
gzwrite($gzip, file_get_contents($sourceDir . $file));
gzclose($gzip);
$count++;
}
echo "成功压缩文件:" . $count . PHP_EOL;
function forFile(string $dir, string $prefix = '') {
foreach (scandir($dir) as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$path = "$dir/$file";
if (is_file($path)) {
yield $prefix . $file;
} else {
yield from forFile($path, $prefix . $file . '/');
}
}
}预压缩文件生成
php gzip.php /www/html重启nginx,打开浏览器验证下预压缩是否成功。(可尝试删除原文件再请求,如果能正常请求说明静态压缩配置成功)
注意:通过nginx指定压缩文件再附加压缩header头信息容易有兼容问题,部分浏览器会屏蔽请求并提示 net::ERR_CONTENT_DECODING_FAILED 错误,比如谷歌浏览器
















