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;
# 最少压缩响应体长度,过小的文件压缩意义不大
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,不利于服务器性能利用。
提前将要请求的静态文件进行压缩,然后通过配置请nginx响应出去即可拦截nginx压缩又能实现http压缩功能会大大减少nginx压缩开销。
nginx配置
# 静态文件进行预压缩
location ~ .*\.(html|js|css)$ {
# 低端浏览器不走预压缩
if ( $http_user_agent ~* 'MSIE [4-6]' ) {
root /www/html; # 无压缩目录
}
# 高端浏览器走预压缩
if ( $http_user_agent !~* 'MSIE [4-6]' ) {
gzip off; # 强制关闭压缩,如果外层没有开过可去掉
root /www/gzip; # 预压缩目录
add_header Vary Accept-Encoding;
add_header Content-Encoding gzip; # 压缩头信息
}
# 没有预压缩文件就取未压缩文件
if (!-e $request_filename) {
root /www/html;
}
}
预压缩脚本
预压缩脚本代码:保存文件 gzip.php
<?php
if (!extension_loaded('zlib')) {
die("请安装 zlib 扩展");
}
if ($argc < 2) {
die("
批量压缩目录内所有文件,压缩成gzip格式
命令:
php {$argv[0]} source-dir [target-dir]
参数:
source-dir 要压缩的目录
target-dir 压缩到指定目录
说明:
此脚本用来快速预压缩文件,用于预压缩http请求静态文件
");
}
$dir = $argv[1];
if (!is_dir($dir)) {
die('目录不存在:' . $dir);
}
$targetDir = $argv[2] ?? './gzip/';
mkdirs($targetDir);
$targetDir = realpath($targetDir) . '/';
$sourceDir = realpath($dir) . '/';
$count = 0;
foreach (forFile($sourceDir) as $file) {
mkdirs($targetDir . dirname($file));
$targetFile = $targetDir . $file;
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 . '/');
}
}
}
function mkdirs(string $path) {
if (!is_dir($path) && !mkdir($path, 0777, true)) {
die("目录创建失败:$path");
}
}
预压缩文件生成
php gzip.php /www/html /www/gzip
重启nginx,打开浏览器验证下预压缩是否成功。
标签:文件,浏览器,静态,压缩,nginx,gzip,http From: https://blog.51cto.com/php2012web/8451535