启用Gzip/Brotli压缩技术
启用Gzip/Brotli压缩技术
现代Web应用中,资源文件体积直接影响页面加载速度。Gzip和Brotli作为两种主流压缩算法,能显著减小文本类资源的传输大小。通过合理配置服务器压缩策略,通常可实现50%-70%的压缩率,这对提升首屏加载速度具有直接效果。
压缩技术原理剖析
Gzip基于DEFLATE算法,使用LZ77算法和哈夫曼编码的组合。当服务器检测到客户端支持gzip时,会对响应体进行压缩并在响应头中添加Content-Encoding: gzip
。典型压缩流程:
- 查找重复字符串并用指针替换
- 使用动态哈夫曼编码减少字符表示位数
- 输出压缩后的比特流
Brotli是Google开发的更新算法,采用LZ77的变种与二阶上下文建模。相比Gzip,Brotli的字典包含13000多个常见Web资源中的字符串模式,这使得它在压缩HTML/CSS/JS时效率更高。Brotli的压缩级别范围是0-11,而Gzip是1-9。
服务器配置实战
Nginx启用双压缩
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 256;
gzip_comp_level 6;
brotli on;
brotli_types text/plain text/css application/json application/javascript;
brotli_comp_level 6;
brotli_static on;
}
关键参数说明:
gzip_min_length
:小于该值的文件不压缩brotli_static
:优先发送预压缩的.br文件- 压缩级别建议设为4-6,更高级别消耗CPU但收益递减
Node.js中间件配置
const compression = require('compression')
const express = require('express')
const app = express()
// 优先尝试Brotli,回退到Gzip
app.use(compression({
filter: shouldCompress,
threshold: 0,
brotli: {
quality: 5
}
}))
function shouldCompress(req, res) {
// 排除已压缩的二进制文件
if (req.headers['x-no-compression']) return false
return compression.filter(req, res)
}
前端构建优化配合
Webpack插件生成预压缩文件:
const CompressionPlugin = require('compression-webpack-plugin')
const BrotliPlugin = require('brotli-webpack-plugin')
module.exports = {
plugins: [
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8
}),
new BrotliPlugin({
asset: '[path].br',
test: /\.(js|css|html|svg)$/,
quality: 11
})
]
}
构建后会同时生成:
- original.js
- original.js.gz
- original.js.br
缓存策略与内容协商
正确处理缓存头避免重复压缩:
HTTP/1.1 200 OK
Content-Type: text/javascript
Content-Encoding: br
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000
关键要点:
Vary: Accept-Encoding
确保为不同客户端缓存不同版本- CDN需要支持传递Accept-Encoding头
- 预压缩文件应设置更长缓存时间
性能对比实测数据
使用WebPageTest对典型SPA应用测试:
压缩方式 | 资源大小 | 传输体积 | CPU耗时 |
---|---|---|---|
无压缩 | 2.1MB | 2.1MB | 0ms |
Gzip | 2.1MB | 543KB | 23ms |
Brotli | 2.1MB | 498KB | 45ms |
移动网络环境下(Slow 3G):
- 无压缩:加载时间8.7s
- Gzip:加载时间3.2s
- Brotli:加载时间2.9s
异常情况处理方案
当遇到客户端不支持时,需要回退机制:
// 检查Accept-Encoding头
const acceptsEncoding = req.headers['accept-encoding']
const supportsGzip = acceptsEncoding.includes('gzip')
const supportsBrotli = acceptsEncoding.includes('br')
// 服务端选择逻辑
if (supportsBrotli && hasBrotliPrecompressed) {
sendBr()
} else if (supportsGzip) {
sendGzip()
} else {
sendRaw()
}
常见问题排查:
- 检查Nginx错误日志中的
brotli
模块加载状态 - 确保MIME类型正确(如application/wasm不应压缩)
- 动态内容建议采用chunked编码压缩
高级调优技巧
对于特定内容类型的优化:
-
JSON API响应:
- 启用字典训练(Brotli特有)
- 设置
Content-Type: application/json+br
-
SVG图像:
gzip_types image/svg+xml; brotli_types image/svg+xml;
-
WebAssembly:
- 禁止压缩.wasm文件
- 添加
wasm-unsafe-eval
CSP策略
-
动态内容压缩:
gzip_proxied any; gzip_disable "msie6";
浏览器支持现状
通过特征检测实现渐进增强:
// 检测Brotli支持
const brotliSupported = () => {
const headers = new Headers()
headers.append('Accept-Encoding', 'br')
return fetch('/test.txt', { headers })
.then(res => res.headers.get('content-encoding') === 'br')
}
各浏览器支持情况:
- Brotli:Chrome 49+、Firefox 44+、Edge 15+
- Gzip:所有现代浏览器
- IE11仅支持Gzip且存在部分bug
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:减少HTTP请求数量的方法
下一篇:合理使用CDN加速静态资源