压缩配置 #

概述 #

压缩是减少网络传输数据量的关键技术,Caddy 内置支持 Gzip 和 Zstandard 压缩算法,可以有效减少带宽使用和加载时间。

text
┌─────────────────────────────────────────────────────────────┐
│                    压缩工作流程                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│    客户端请求                                                │
│    Accept-Encoding: gzip, deflate, br, zstd                 │
│         ↓                                                   │
│    Caddy 检查支持的压缩算法                                   │
│         ↓                                                   │
│    选择最佳压缩算法                                          │
│         ↓                                                   │
│    压缩响应内容                                              │
│         ↓                                                   │
│    返回压缩后的响应                                          │
│    Content-Encoding: gzip                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本配置 #

启用压缩 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 启用 Gzip 压缩
    encode gzip
}

多种压缩算法 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 同时启用多种压缩算法
    # Caddy 会根据客户端支持选择最优算法
    encode gzip zstd
}

压缩算法优先级 #

Caddy 按照以下优先级选择压缩算法:

text
zstd > gzip > (不压缩)

压缩算法详解 #

Gzip #

最广泛支持的压缩算法:

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # Gzip 压缩
    encode gzip
}

Gzip 压缩级别 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 指定压缩级别 (1-9)
    # 1: 最快压缩,最低压缩率
    # 9: 最慢压缩,最高压缩率
    # 推荐: 4-6 平衡压缩率和速度
    encode {
        gzip 6
    }
}

Gzip 压缩级别对比 #

级别 压缩率 速度 CPU 使用 推荐场景
1 最快 实时内容
4 一般网站
6 较高 中等 推荐
9 最高 最慢 静态内容

Zstandard (Zstd) #

新一代压缩算法,更好的压缩率和速度:

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # Zstd 压缩
    encode zstd
}

Zstd 压缩级别 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # Zstd 压缩级别 (1-19)
    # 推荐: 3-5 平衡压缩率和速度
    encode {
        zstd 5
    }
}

算法对比 #

特性 Gzip Zstd
浏览器支持 广泛 较新
压缩率 中等
压缩速度 中等
解压速度 中等
CPU 使用 中等

完整压缩配置 #

基本完整配置 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    encode {
        # 压缩算法
        gzip 6
        zstd 5
        
        # 最小压缩大小
        minimum_length 256
        
        # 排除不压缩的类型
        except image/* video/* audio/* application/pdf
    }
}

高级压缩配置 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    encode {
        # Gzip 配置
        gzip 6 {
            # 最小长度
            min_length 256
        }
        
        # Zstd 配置
        zstd 5
        
        # 排除特定 MIME 类型
        except {
            image/*
            video/*
            audio/*
            application/pdf
            application/zip
            application/x-rar-compressed
        }
    }
}

条件压缩 #

基于路径压缩 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 只压缩特定路径
    @compressable path /api/* /data/*
    encode @compressable gzip zstd
}

基于文件类型压缩 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 压缩文本类文件
    @text {
        path *.html *.css *.js *.json *.xml *.txt *.svg
    }
    encode @text gzip zstd
}

基于响应类型压缩 #

caddyfile
example.com {
    reverse_proxy localhost:3000
    
    # 压缩 API 响应
    encode gzip zstd
}

预压缩文件 #

Caddy 支持自动提供预压缩文件:

配置预压缩 #

caddyfile
example.com {
    root * /var/www/html
    file_server {
        # 启用预压缩支持
        precompressed
        
        # 或指定格式
        precompressed gzip zstd br
    }
}

预压缩文件结构 #

text
/var/www/html/
├── style.css           # 原始文件
├── style.css.gz        # Gzip 压缩
├── style.css.zst       # Zstd 压缩
├── app.js
├── app.js.gz
└── app.js.zst

生成预压缩文件 #

bash
# Gzip 压缩
gzip -k -6 style.css

# Zstd 压缩
zstd -6 style.css -o style.css.zst

# 批量压缩
find /var/www/html -type f \( -name "*.css" -o -name "*.js" \) -exec gzip -k -6 {} \;
find /var/www/html -type f \( -name "*.css" -o -name "*.js" \) -exec zstd -6 {} -o {}.zst \;

压缩排除 #

排除特定类型 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    encode {
        gzip
        zstd
        
        # 排除已压缩的格式
        except {
            image/*
            video/*
            audio/*
            application/pdf
            application/zip
            application/x-gzip
            application/x-rar-compressed
            application/x-7z-compressed
        }
    }
}

排除特定路径 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    # 不压缩下载文件
    @nocompress path /downloads/*
    
    encode gzip zstd
}

压缩验证 #

测试压缩 #

bash
# 测试是否启用压缩
curl -H "Accept-Encoding: gzip, zstd" -I https://example.com/style.css

# 查看响应头
# Content-Encoding: gzip
# Vary: Accept-Encoding

比较压缩效果 #

bash
# 未压缩大小
curl -s https://example.com/style.css | wc -c

# 压缩后大小
curl -s -H "Accept-Encoding: gzip" https://example.com/style.css | wc -c

# 压缩率
echo "scale=2; (1 - 压缩后/未压缩) * 100" | bc

使用 curl 测试 #

bash
# 测试 Gzip
curl -H "Accept-Encoding: gzip" -I https://example.com/

# 测试 Zstd
curl -H "Accept-Encoding: zstd" -I https://example.com/

# 查看压缩内容(需要解压)
curl -H "Accept-Encoding: gzip" https://example.com/ | gunzip

性能优化 #

压缩级别选择 #

caddyfile
# 静态内容 - 高压缩率
example.com {
    root * /var/www/static
    file_server
    encode {
        gzip 9
        zstd 19
    }
}

# 动态内容 - 平衡压缩
api.example.com {
    reverse_proxy localhost:3000
    encode {
        gzip 4
        zstd 3
    }
}

# 实时内容 - 低延迟
realtime.example.com {
    reverse_proxy localhost:3000
    encode {
        gzip 1
        zstd 1
    }
}

最小压缩大小 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    encode {
        gzip
        minimum_length 512  # 小于 512 字节不压缩
    }
}

内存优化 #

caddyfile
# 高并发场景
example.com {
    root * /var/www/html
    file_server
    
    encode {
        gzip 4  # 较低压缩级别,减少内存使用
        minimum_length 1024
    }
}

完整示例 #

静态网站压缩 #

caddyfile
example.com {
    root * /var/www/html
    file_server
    
    encode {
        gzip 6
        zstd 5
        minimum_length 256
        except {
            image/*
            video/*
            audio/*
            application/pdf
        }
    }
    
    # 预压缩支持
    file_server {
        precompressed
    }
    
    # 缓存头部
    header Vary "Accept-Encoding"
}

API 服务压缩 #

caddyfile
api.example.com {
    reverse_proxy localhost:3000
    
    encode {
        gzip 4
        zstd 3
        minimum_length 128
    }
    
    # 响应头部
    header {
        Vary "Accept-Encoding"
        Content-Type "application/json"
    }
}

多站点压缩配置 #

caddyfile
# 共享压缩配置
(compression) {
    encode {
        gzip 6
        zstd 5
        minimum_length 256
    }
}

site1.example.com {
    import compression
    root * /var/www/site1
    file_server
}

site2.example.com {
    import compression
    reverse_proxy localhost:3000
}

电商网站压缩 #

caddyfile
shop.example.com {
    root * /var/www/shop
    file_server
    
    # 静态资源压缩
    @static path /static/* /assets/* /images/*
    handle @static {
        encode {
            gzip 9
            zstd 19
        }
        file_server {
            precompressed
        }
    }
    
    # API 压缩
    handle /api/* {
        encode {
            gzip 4
            zstd 3
        }
        reverse_proxy localhost:3000
    }
    
    # HTML 压缩
    handle {
        encode {
            gzip 6
            zstd 5
        }
        file_server
    }
    
    header Vary "Accept-Encoding"
}

压缩最佳实践 #

1. 选择合适的压缩级别 #

caddyfile
# 静态资源:高压缩率
encode gzip 9

# 动态内容:平衡
encode gzip 4-6

# 实时内容:低延迟
encode gzip 1-2

2. 设置最小压缩大小 #

caddyfile
# 避免压缩小文件
encode {
    gzip
    minimum_length 256
}

3. 排除已压缩格式 #

caddyfile
encode {
    gzip
    except {
        image/*
        video/*
        application/pdf
        application/zip
    }
}

4. 使用预压缩 #

caddyfile
file_server {
    precompressed
}

5. 设置 Vary 头部 #

caddyfile
header Vary "Accept-Encoding"

常见问题 #

Q: 为什么压缩没有生效? #

bash
# 检查客户端是否发送 Accept-Encoding
curl -v https://example.com/ 2>&1 | grep Accept-Encoding

# 检查响应是否包含 Content-Encoding
curl -H "Accept-Encoding: gzip" -I https://example.com/ | grep Content-Encoding

# 检查文件类型是否被排除
# 检查文件大小是否小于 minimum_length

Q: 压缩后反而变大了? #

caddyfile
# 设置最小压缩大小
encode {
    gzip
    minimum_length 1024  # 小文件不压缩
}

Q: CPU 使用过高? #

caddyfile
# 降低压缩级别
encode {
    gzip 3
    zstd 2
}

下一步 #

现在你已经掌握了压缩配置,接下来学习 访问控制 了解如何保护你的网站!

最后更新:2026-03-28