如何压缩响应体?

访客 性能优化 2

本文目录导读:

  1. 核心原则
  2. 在 Web 服务器层面配置(最推荐)
  3. 在应用代码或框架中配置(后端开发)
  4. 通过反向代理/API 网关(生产环境推荐)
  5. 调试与验证
  6. 关键注意事项
  7. 总结步骤

压缩响应体是提升 Web 应用性能、减少带宽消耗和加快页面加载速度的关键手段,最常用的方法是启用 GzipBrotli 压缩。

下面是针对不同场景的具体实现方案。

核心原则

绝大多数现代 Web 服务器和浏览器都支持 Gzip 压缩。Brotli 是较新的算法,压缩率通常比 Gzip 高 20-30%,但需要更长的压缩时间(通常问题不大)。


在 Web 服务器层面配置(最推荐)

这是最常见的做法,无需修改代码,服务器在返回响应给客户端之前自动完成压缩。

A. Nginx

Nginx 默认已编译了 Gzip 模块,通常只需在 nginx.conf 或站点配置文件中启用。

http {
    # 启用 Gzip
    gzip on;
    # 至少 1KB 才压缩,避免压缩过小文件
    gzip_min_length 1024;
    # 设置缓冲区
    gzip_buffers 4 16k;
    # HTTP 1.1 以上才压缩(兼容 HTTP 1.0)
    gzip_http_version 1.1;
    # 压缩级别 1-9,推荐 4-6(平衡效率与压缩率)
    gzip_comp_level 5;
    # 压缩的文件类型(文本类效果最佳)
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/json image/svg+xml;
    # 让 Vary 头生效,代理服务器正确处理
    gzip_vary on;
    # 禁止对 IE6 进行压缩
    gzip_disable "msie6";
}

启用 Brotli(需要额外安装模块):

http {
    # 需要安装 ngx_brotli 模块
    brotli on;
    brotli_comp_level 6;  # 0-11
    brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
}

注意: 如果同时启用了 Gzip 和 Brotli,现代浏览器会优先使用 Brotli,因为它在请求头中会声明 Accept-Encoding: br

B. Apache

Apache 使用 mod_deflate 模块。

<IfModule mod_deflate.c>
    # 启用压缩
    SetOutputFilter DEFLATE
    # 仅对特定 MIME 类型压缩(推荐)
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml
    # 排除老旧的浏览器
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    # 设置压缩级别(1-9)
    DeflateCompressionLevel 5
</IfModule>

C. IIS (Windows Server)

  1. 打开 IIS 管理器
  2. 选择站点 -> 压缩
  3. 勾选 启用静态内容压缩启用动态内容压缩
  4. 对于更精细的控制,可以编辑 applicationHost.config 文件。

在应用代码或框架中配置(后端开发)

如果你没有服务器根权限,或者想对特定 API 路由进行控制。

A. Node.js (Express/Koa)

使用 compression 中间件:

const express = require('express');
const compression = require('compression');
const app = express();
// 使用默认配置(Gzip)
app.use(compression());
// 或者自定义配置
app.use(compression({
    threshold: 1024,       // 只压缩大于 1KB 的响应
    level: 5,              // 压缩级别
    filter: (req, res) => {
        // 自定义过滤:不对图片进行压缩
        if (req.headers['content-type'] && req.headers['content-type'].includes('image')) {
            return false;
        }
        return true; // 默认对所有内容压缩
    }
}));

B. Java (Spring Boot)

Spring Boot 内置了压缩支持,只需在 application.propertiesapplication.yml 中配置:

# application.properties
server.compression.enabled=true
# 压缩的 MIME 类型
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# 最小响应大小(字节)
server.compression.min-response-size=1024

C. Python (Flask/Django)

使用 Gzip 中间件:

# Flask 示例
from flask import Flask
from flask_compress import Compress
app = Flask(__name__)
# 初始化压缩
compress = Compress()
compress.init_app(app)
# 或直接使用
# app.config['COMPRESS_MIMETYPES'] = ['text/html', 'text/css', 'application/json']
# app.config['COMPRESS_LEVEL'] = 5
# app.config['COMPRESS_MIN_SIZE'] = 500
# Compress(app)
# Django 示例(settings.py 中)
MIDDLEWARE = [
    # 建议放在靠前的位置
    'django.middleware.gzip.GZipMiddleware',
    # ... 其他中间件
]
# 注意:Django 的 GZipMiddleware 会自动忽略小于 200 字节的响应。

D. Go (Gin/标准库)

import "github.com/gin-gonic/gin"
func main() {
    r := gin.Default()
    // 使用 Gzip 中间件
    r.Use(gin.Logger())
    r.Use(gin.Recovery())
    r.GET("/data", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "Hello World!"})
    })
    r.Run()
}

通过反向代理/API 网关(生产环境推荐)

如果你的应用后端没有压缩,可以通过反向代理(如 Nginx、Envoy、Kong、AWS CloudFront)压缩。

  • AWS CloudFront / Cloudflare:默认启用自动压缩(Gzip 和 Brotli)。
  • Nginx 反向代理:配置如上文。
  • HAProxy:支持 compression 指令。

调试与验证

配置完成后,必须验证是否生效,打开浏览器的 开发者工具 -> 网络

  1. 刷新页面,点击任意一个资源(如 HTML、JS、CSS)。
  2. 查看 响应头
    • Gzip:应包含 Content-Encoding: gzip
    • Brotli:应包含 Content-Encoding: br
  3. Size 列:通常显示两个数值,如 “33.2 KB / 120.0 KB”,前者是压缩后大小,后者是原始大小。

也可以使用 curl 命令行:

# 查看响应头中的 Content-Encoding
curl -I -H "Accept-Encoding: gzip, deflate" https://your-api.com/data

关键注意事项

  1. 不要压缩二进制文件

    • 图片(JPEG, PNG, GIF, WebP)
    • 已压缩的格式(ZIP, MP4, PDF)
    • 这些文件通常已内置压缩,再次压缩会浪费 CPU 且效果极差。
  2. 动态 vs 静态压缩

    • 静态压缩(预压缩):对于静态 JS/CSS 文件,可以预先压缩成 .gz 文件,服务器直接发送,节省实时 CPU 开销。
    • 动态压缩:对 API 返回的动态 JSON 实时压缩。
  3. 安全风险(如 BREACH 攻击)

    • 对于包含敏感数据(CSRF Token、Session ID)的,启用压缩可能增加信息泄露风险,如果对安全性要求极高(如支付页面),可以考虑禁用压缩。
  4. 极小响应不要压缩

    • 如果响应体小于 1KB,压缩后的头信息和压缩运算可能得不偿失,配置 threshold 是一个好习惯。

总结步骤

  1. 优先配置 Web 服务器(Nginx/Apache),这是最简单、最高效的方式。
  2. 如果服务器无法配置,在应用框架中增加 Gzip 中间件。
  3. 使用 Brotli(如果支持),可获得更好的压缩率。
  4. 通过浏览器开发工具验证 Content-Encoding 头。
  5. 注意安全与性能的平衡,排除二进制文件。

标签: Gzip压缩 响应体优化

抱歉,评论功能暂时关闭!