Nginx功能篇02—压缩响应

概述

本章,您将了解到 Nginx 的压缩响应功能。

启用压缩响应功能

前面在说明 nginx.conf 时,提到了这样的一个指令:

gzip 指令 - 是否开启 Gzip 压缩响应功能,即告诉 Nginx 服务器在发送响应数据给客户端(如浏览器)之前,先对数据进行 Gzip 算法压缩

一个大型的导航网站,其静态资源(图片、JS、html、CSS等)是非常多的,若不启用压缩响应功能,单页面的大小是非常大的,但你也知道,服务器的带宽资源是有上限的,因此,绝大多数的网站都建议启用压缩响应功能。

涉及到的指令有(这些指令可配置在 http 上下文中,也可以配置在 server 上下文中):

  • gzip 指令 - 是否启用 Gzip 压缩响应功能

  • gzip_buffers 指令 - 设置用于压缩响应的缓冲区数量和大小,语法为 gzip_buffers number size;。默认情况下,一个缓冲区等于一个内存页大小,不同操作系统平台的缓冲区大小为 4K 或 8K,在 GNU/Linux 中,一个内存页大小等于 4K。默认为 gzip_buffers 32 4K;

    Shell > getconf PAGE_SIZE
    4096
  • gzip_comp_level 指令 - 设置压缩的级别,语法为 gzip_comp_level level;,压缩级别的取值范围为 1-9。理论上,数字越大压缩率越高,但在实际生产环境中,会在 "带宽节省" 与 "CPU 资源消耗" 之间找到最佳平衡点。默认为 gzip_comp_level 1;

  • gzip_types 指令 - 除 text/html 之外,对哪些 MIME 类型进行压缩,语法为 gzip_types mime-type ...;。默认为 gzip_types text/html;。MIME 类型可通过 /usr/local/nginx/conf/mime.types 进行查看

  • gzip_min_length 指令 - Gzip 压缩响应的最小长度,这里的 "长度" 指的是 ‌HTTP 响应体(Response Body)的大小‌,单位是 ‌字节(Bytes)。该长度仅根据 HTTP 响应头中的 "Content-Length" 字段进行确定。默认为 gzip_min_length 20;

  • gzip_vary 指令 - 是否在 HTTP 响应头中添加 "Vary: Accept-Encoding" 字段。该指令的主要作用是确保缓存系统(如CDN、反向代理)能够正确区分同一资源的 "压缩版本" 和 "未压缩版本",从而避免缓存污染导致的页面乱码或加载失败。在生产环境中,通常都强烈配置为 gzip_vary on;

    • 缓存污染(Cache Poisoning)- 假设用户 A 的浏览器(支持 Gzip)访问了 style.css,Nginx 会返回压缩后的二进制数据,并被 CDN (Content Delivery Network,内容分发网络)缓存。随后,B 用户的旧版浏览器(不支持 Gzip)也访问了同一个 style.css 资源,此时,由于 CDN 缓存系统认为 URL (统一资源定位)相同,因此返回了之前已缓存的‌压缩二进制数据,这导致 B 用户浏览器的页面会出现如 CSS 解析失败、页面样式丢失、JS 报错或显示乱码等情况

一个适用于生产环境的简易配置:

...
http {
    ...
    gzip on;
    gzip_vary on;
    gzip_buffers 32 4K;
    gzip_comp_level 5;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xhtml+xml image/svg+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject font/woff;
    gzip_min_length 256;
    ...
}
...

不对图片启用压缩的原因 —— 主流图片格式(JPEG、PNG、WebP、GIF)在生成时已经内置了专用的高效压缩算法,冗余信息极少,若对这些图片再次使用 Gzip 二次压缩,压缩后的文件大小并没有减少多少反而额外消耗了 CPU 性能,所以这种优化手段并不划算。

在生产环境中,若 Nginx 的压缩响应功能已经配置完成,可通过以下命令进行验证(比如 CSS 资源):

Shell > curl -I -H "Accept-Encoding: gzip" https://www.example.com/main.js

预期的输出:

Content-Encoding: gzip
Vary: Accept-Encoding

您也可以通过 Google Chrome 的 F12 快捷键进入到开发者页面,在 Network 标签页下方的资源列表中选中相关的文件(js、css、json等),即可在右侧的详情面板中找到相关的响应标头。

当前作者 nginx.conf 的内容为:

Shell > cat /usr/local/nginx/conf/nginx.conf
user  nginx;
worker_processes  4;

error_log  logs/error.log  error;

pid        logs/nginx.pid;

worker_rlimit_nofile 7400;

events {
    use epoll;
    worker_connections  1024;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    sendfile       on;
    tcp_nopush     on;

    keepalive_timeout  30;

    gzip on;
    gzip_vary on;
    gzip_buffers 32 4K;
    gzip_comp_level 5;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xhtml+xml image/svg+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject font/woff;
    gzip_min_length 256;

    server {
        listen  192.168.100.20:80;
        server_name  www.games.com;
        access_log  logs/games-access.log  main;
        charset utf-8;

        location / {
            root   /html/games/;
            index  index.html index.htm;
        }
    }
}

补充内容

若用户的浏览器版本不是太旧且追求极致的性能,在生产环境中除了开启 Gzip 压缩响应外,还会另外开启 Brotli 压缩算法。

Brotli 压缩算法:Google 在 2015 年发布的一种通用无损压缩算法,现已成为现代 Web 性能优化的标配之一。主要特点有:

  • 压缩率高 - 在相同压缩级别下,Brotli 对文本的压缩率通常比 Gzip 高 15% ~ 20%,这意味着 CSS、JS、HTML 等文本资源传输体积更小,页面加载更快。
  • 解压速度快 - 虽然高压缩级别下压缩过程比 Gzip 慢,但解压速度非常快,对浏览器几乎没有额外负担
  • 天然的压缩优势 - Brotli 内置了对 ASCII、UTF-8 的优化,并且使用了预定义的字典,这让它在压缩 Web 资源时天然占优。

需要注意的是,Nginx 默认情况下没有集成 Brotli 模块,使用者需要手动编译安装 ngx_brotli 模块。

在使用 Brotli 压缩算法时,通常会有动态压缩和静态预压缩两种压缩方式,这两种方式可以同时在 Nginx 中共存。

  • 动态压缩 - 当用户的浏览器请求静态资源时,Nginx 发现用户的浏览器支持 Brotli 压缩算法,于是便实时调用 CPU 对相关的静态资源进行压缩处理,完成后把压缩数据发送给浏览器。
  • 静态预压缩 - 在 Web 服务器上,对于那些不经常变动的静态资源可以采用静态预压缩。在 Nginx 中配置之前,您需要首先使用相关的命令行工具(如 brotli 命令)手动压缩相关的静态资源,此时 Web 服务器上会存在同一静态资源的压缩版本(使用 ".br" 的文件后缀)和未压缩版本。完成后,需要在 Nginx 的主配置文件中配置 brotli_static on;。当浏览器请求对应静态资源时,就会在服务器上查找对应静态资源的 ".br" 文件,如果有,直接把这个文件发给浏览器,完全跳过压缩计算的过程。

生产环境中的配置示例:

...
http {
    ...
    gzip on;
    gzip_vary on;
    gzip_buffers 32 4K;
    gzip_comp_level 5;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xhtml+xml image/svg+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject font/woff;
    gzip_min_length 256;
    ...

    # --- Brotli 动态压缩配置 ---
    brotli on;
    brotli_comp_level 6;
    brotli_types text/plain text/css text/xml application/json application/javascript application/xml application/xhtml+xml image/svg+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject font/woff;
    brotli_min_length 256;

    # --- Brotli 静态预压缩(强烈推荐) ---
    # 如果找不到 .br 文件,才会进行动态压缩
    brotli_static on;
    ...
}
...
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇