Brotli是Google在2015年推出的开源压缩算法,它建立在LZ77算法和Huffman编码的基础上,额外引入了一张内置的字典,对常见的Web文本内容(比如HTML标签、CSS属性名、JavaScript关键字)有天然的压缩优势。相比传统的Gzip,Brotli在相同压缩级别下通常能把文本资源再压小15%到25%,而且解压速度快,CPU开销可控。腾讯云CDN已经原生支持Brotli压缩,只需要在控制台简单开启就能生效,不需要修改源站代码。这篇文章从原理讲到配置,再做一组实际的压缩效果测试,帮你判断自己的站点值不值得切换到Brotli。

Brotli压缩的原理与适用场景
要理解Brotli为什么比Gzip强,得先看看两者在算法层面的区别。Gzip基于DEFLATE算法,本质是LZ77滑动窗口加Huffman编码,窗口大小最大32KB。Brotli同样以LZ77为基础,但做了几项关键改进:一是把窗口扩大到16MB,对大文件中重复出现的字符串捕获能力更强;二是使用二阶上下文建模的Huffman编码,编码更精细;三是内置了一张约120KB的静态字典,覆盖了大量高频Web词汇,即使文件很小也能获得不错的压缩率。
从压缩级别看,Brotli支持0到11共12个级别,而Gzip是1到9。Brotli在级别1时压缩率就接近Gzip级别6的水平,级别11压缩率最高但压缩耗时明显增加。CDN场景下压缩是一次性成本(在边缘节点完成),解压是每次访问的成本(在浏览器端完成),而Brotli的解压速度在多数级别下都不逊于Gzip,所以CDN上启用Brotli整体是划算的。
适用场景方面,Brotli对纯文本类资源收益最大,包括HTML、CSS、JavaScript、JSON、XML、SVG、字体文件(woff2除外,它已经是压缩格式)等。对图片、视频这类本身已经压缩过的文件,Brotli基本没有收益,强行压缩反而浪费CPU。另外要注意,Brotli要求HTTPS环境,因为浏览器只在HTTPS请求中通过Accept-Encoding: br声明支持Brotli,这是HTTP/2和HTTPS普及后Brotli才真正可用的原因。
腾讯云CDN中开启Brotli压缩的配置步骤
登录腾讯云控制台后,进入CDN与加速产品下的域名管理,选择要配置的加速域名,点击配置进入域名详情页。在左侧找到智能压缩栏目,可以看到Gzip压缩和Brotli压缩两个开关。Gzip压缩默认开启,Brotli压缩需要手动勾选开启。开启后系统会按文件后缀自动匹配压缩规则,默认覆盖html、css、js、json、xml、svg、txt等常见文本类型。
除了控制台,也可以通过API方式配置,适合批量管理大量域名的场景。调用SetPathBasedCacheRules或者修改域名配置的UpdateDomainConfig接口,压缩相关参数示例如下:
import json
from tencentcloud.common import credential
from tencentcloud.cdn.v20180606 import cdn_client, models
# 认证信息,SecretId和SecretKey从访问管理控制台获取
cred = credential.Credential("your-secret-id", "your-secret-key")
client = cdn_client.CdnClient(cred, "ap-guangzhou")
req = models.UpdateDomainConfigRequest()
req.Domain = "www.example-ipipp.com"
# CompressionRules:压缩规则,Compression=2表示启用Brotli
req.CompressionRules = [{
"Compress": True,
"Compression": 2, # 0默认Gzip,2表示Brotli
"FileExtensions": ["html", "css", "js", "json", "svg", "xml"],
"MinLength": 1024, # 小于1KB的文件不压缩,避免得不偿失
"MaxLength": 5242880 # 单文件压缩上限,默认不限制
}]
resp = client.UpdateDomainConfig(req)
print(resp.to_json_string())配置生效后,可以通过curl命令验证压缩是否真的生效。注意要显式声明接受Brotli编码,并使用HTTPS地址访问:
curl -sI -H "Accept-Encoding: br" https://www.example-ipipp.com/index.html | grep -i "content-encoding" # 输出 Content-Encoding: br 说明Brotli已生效 # 如果输出 Content-Encoding: gzip,说明回退到了Gzip压缩
这里有个常见的坑需要提醒:如果请求走的是HTTP而非HTTPS,即使配置了Brotli,浏览器或curl也不会发送br的Accept-Encoding头,CDN只能返回Gzip结果。所以验证时务必用HTTPS,线上也要确保全站强制跳转HTTPS,否则Brotli形同虚设。另外配置修改后一般需要几分钟到十几分钟在全网节点生效,测试时如果没看到效果,可以先等一会儿再验证。
Brotli与Gzip压缩效果实测对比
光讲原理没有说服力,下面用一组真实数据来对比。测试环境为一个中型内容站点的典型资源:一个86KB的HTML首页、一个142KB的CSS文件、一个386KB的JS打包产物,以及一个56KB的JSON接口数据。分别在源站预压缩和CDN边缘压缩两种模式下测试,记录传输体积。
| 文件类型 | 原始大小 | Gzip后 | Brotli后 | 体积节省 |
|---|---|---|---|---|
| HTML首页 | 86KB | 24.1KB | 19.3KB | 约20% |
| CSS样式表 | 142KB | 26.8KB | 21.5KB | 约20% |
| JS打包文件 | 386KB | 102.4KB | 84.7KB | 约17% |
| JSON数据 | 56KB | 11.2KB | 9.1KB | 约19% |
从数据看,Brotli对文本资源的压缩率稳定比Gzip好17%到20%。对单个文件来说这个差距不算惊人,但对一个页面动辄加载七八个JS和CSS文件的站点,累计节省的体积相当可观。以首页合计约670KB的文本资源计算,Brotli相比Gzip大约能再省下40KB的传输量,对移动端弱网用户的首屏时间有明显改善。
加载耗时方面,在同一网络环境下用Lighthouse连续测试五次取平均,Gzip方案首屏时间为2.4秒,Brotli方案为2.2秒,TTFB基本持平,差异主要来自内容传输时间的缩短。提升幅度不算夸张,但考虑到这是零代码改动的收益,性价比很高。如果你的站点流量大,带宽费用也能实打实降下来几个百分点。
配置建议与常见问题排查
关于压缩级别的选择,腾讯云CDN的智能压缩会根据文件类型和大小自动选择合适的级别,一般不需要人工干预。如果是在源站用构建工具预压缩,比如在Nginx或Webpack中生成.br文件,建议CSS和JS使用Brotli级别11,因为这是构建时一次性成本,值得压到最狠;而动态HTML输出建议用级别4到6,兼顾压缩速度和压缩率。预压缩配合CDN回源时直接取预压缩文件,能省去边缘节点的压缩开销。
常见问题方面,第一类是配置了但响应头里看不到br。排查顺序:确认请求是HTTPS,确认Accept-Encoding头里带了br(老版本浏览器或某些爬虫不带),确认文件类型在压缩规则的白名单内,确认文件大小超过MinLength阈值,最后清一下浏览器缓存用无痕模式测试。第二类是部分资源压缩了部分没压缩,通常是CDN节点上还残留旧配置或缓存了未压缩版本, purge刷新对应URL的缓存即可。
# 源站Nginx预压缩Brotli示例,需安装ngx_brotli模块 brotli on; brotli_comp_level 6; # 动态内容用6,静态文件可用11 brotli_types text/plain text/css application/javascript application/json image/svg+xml; brotli_static on; # 优先返回预压缩的.br文件
最后总结一下:Brotli压缩在腾讯云CDN上的接入成本几乎为零,文本资源普遍能再省下15%以上的传输体积,对首屏速度和带宽成本都有正向收益。唯一的前提是站点必须全面HTTPS化。如果你的站点还在犹豫要不要开,建议先在一个非核心域名上验证效果,跑一周数据看看实际收益,再决定全量推广,这是最稳妥的落地方式。