資料壓縮:Gzip vs Brotli
壓縮是減少傳輸資料量的最直接方式。本篇將深入解析 HTTP 壓縮機制與兩大主流算法。
一、 為什麼需要壓縮?
1.1 效益分析
| 檔案類型 | 原始大小 | Gzip | Brotli |
|---|---|---|---|
| JavaScript | 500KB | 150KB (70%) | 130KB (74%) |
| HTML | 100KB | 20KB (80%) | 17KB (83%) |
| CSS | 200KB | 40KB (80%) | 35KB (82%) |
| JSON | 50KB | 10KB (80%) | 8KB (84%) |
1.2 壓縮流程
二、 Accept-Encoding 標頭
2.1 請求標頭
瀏覽器告訴伺服器支援的壓縮格式:
http
Accept-Encoding: gzip, deflate, br| 值 | 說明 |
|---|---|
| gzip | GNU Zip |
| deflate | Deflate 算法 |
| br | Brotli |
| identity | 不壓縮 |
| * | 任意 |
2.2 回應標頭
伺服器告訴瀏覽器使用的壓縮格式:
http
Content-Encoding: gzip
# 或
Content-Encoding: br三、 Gzip
3.1 特點
- 歷史悠久,支援度最廣
- 壓縮速度快
- 壓縮率適中
- 所有瀏覽器都支援
3.2 Express 配置
javascript
const compression = require("compression");
app.use(
compression({
level: 6, // 1-9,9 最高壓縮率
threshold: 1024, // 超過 1KB 才壓縮
filter: (req, res) => {
if (req.headers["x-no-compression"]) {
return false;
}
return compression.filter(req, res);
},
})
);3.3 Nginx 配置
nginx
http {
gzip on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css application/json
application/javascript text/xml application/xml
application/xml+rss text/javascript;
gzip_vary on;
gzip_proxied any;
}四、 Brotli
4.1 特點
- Google 開發,2015 年發布
- 壓縮率比 Gzip 高 15-25%
- 壓縮速度稍慢
- 需要 HTTPS(大多數瀏覽器要求)
- 現代瀏覽器支援度良好
4.2 Express 配置
javascript
const shrinkRay = require("shrink-ray-current");
app.use(shrinkRay());
// 或手動實作
const { createBrotliCompress } = require("zlib");
app.use((req, res, next) => {
if (!req.headers["accept-encoding"]?.includes("br")) {
return next();
}
// 只對文字類型壓縮
const contentType = res.get("Content-Type");
if (!contentType?.match(/text|json|javascript|xml/)) {
return next();
}
res.set("Content-Encoding", "br");
res.removeHeader("Content-Length");
const brotli = createBrotliCompress();
res.pipe = brotli.pipe.bind(brotli);
next();
});4.3 Nginx 配置
nginx
http {
# 需要 ngx_brotli 模組
brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types text/plain text/css application/json
application/javascript text/xml application/xml
application/xml+rss text/javascript;
}五、 Gzip vs Brotli 比較
5.1 壓縮率比較
5.2 效能比較
| 指標 | Gzip | Brotli |
|---|---|---|
| 壓縮速度 | 快 | 較慢 |
| 解壓速度 | 快 | 快 |
| 壓縮率 | 良好 | 更好 |
| 瀏覽器支援 | 100% | 95%+ |
| HTTPS 要求 | 否 | 是(大多數) |
5.3 何時使用哪個?
六、 預壓縮策略
6.1 為什麼要預壓縮?
動態壓縮消耗 CPU。對於靜態資源,可以在建構時預先壓縮。
6.2 Webpack 配置
javascript
const CompressionPlugin = require("compression-webpack-plugin");
module.exports = {
plugins: [
// Gzip
new CompressionPlugin({
filename: "[path][base].gz",
algorithm: "gzip",
test: /\.(js|css|html|svg)$/,
threshold: 1024,
minRatio: 0.8,
}),
// Brotli
new CompressionPlugin({
filename: "[path][base].br",
algorithm: "brotliCompress",
test: /\.(js|css|html|svg)$/,
threshold: 1024,
minRatio: 0.8,
}),
],
};6.3 Vite 配置
javascript
import viteCompression from "vite-plugin-compression";
export default {
plugins: [
viteCompression({
algorithm: "gzip",
ext: ".gz",
}),
viteCompression({
algorithm: "brotliCompress",
ext: ".br",
}),
],
};6.4 Nginx 使用預壓縮檔
nginx
location ~* \.(js|css|html)$ {
gzip_static on;
brotli_static on;
# 伺服器會自動尋找 .gz 和 .br 檔案
}七、 最佳實踐
7.1 應該壓縮的類型
nginx
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2;7.2 不應該壓縮的類型
- 已壓縮的圖片(JPEG、PNG、WebP)
- 已壓縮的檔案(ZIP、PDF)
- 影片和音訊
- 非常小的檔案(< 1KB)
7.3 完整配置範例
nginx
http {
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/json
application/xml application/xml+rss
image/svg+xml font/woff2;
# Brotli(需要模組)
brotli on;
brotli_comp_level 6;
brotli_min_length 1024;
brotli_types text/plain text/css text/xml text/javascript
application/javascript application/json
application/xml application/xml+rss
image/svg+xml font/woff2;
# 預壓縮檔案
gzip_static on;
brotli_static on;
}八、 效能監控
8.1 檢查壓縮效果
bash
# 使用 curl
curl -I -H "Accept-Encoding: gzip" https://example.com/app.js
# 查看 Content-Encoding 標頭
# 比較大小
curl -sH "Accept-Encoding: identity" https://example.com/app.js | wc -c
curl -sH "Accept-Encoding: gzip" https://example.com/app.js | wc -c8.2 DevTools 分析
Network 面板:
- Size 欄位顯示壓縮後大小
- 點擊請求查看 Content-Encoding
- 比較 transferred 和 resources總結
| 算法 | 壓縮率 | 速度 | 支援度 | 推薦場景 |
|---|---|---|---|---|
| Gzip | 良好 | 快 | 100% | 通用 |
| Brotli | 更好 | 較慢 | 95%+ | HTTPS + 現代瀏覽器 |
> **最佳策略**:
- 優先 Brotli,回退到 Gzip
- 靜態資源使用預壓縮
- 設定合適的 threshold
進階挑戰
- 比較相同檔案在不同壓縮等級下的大小和壓縮時間。
- 實作一個中介軟體,根據 CPU 負載動態調整壓縮等級。
- 研究 Zstandard(zstd)壓縮算法,與 Brotli 比較。