Google 认为互联网用户的时间是宝贵的,他们的时间不应该消耗在漫长的网页加载中,因此在 2015 年 9 月 Google 推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率。
根据 Google 发布的研究报告,Brotli 压缩算法具有多个特点,最典型的是以下 3 个:
- 针对常见的 Web 资源内容,Brotli 的性能相比 Gzip 提高了 17-25%;
- 当 Brotli 压缩级别为 1 时,压缩率比 Gzip 压缩等级为 9(最高)时还要高;
- 在处理不同 HTML 文档时,Brotli 依然能够提供非常高的压缩率。
Brotli 如此高的压缩比率,得益于其使用一个预定义的字典,该字典包含超过 13000 个来自文本和 HTML 文档的大型语料库的常用字符串,预定义的算法可以提升较小文件的压缩密度,而压缩与解压缩速度则大致不变。
Brotli 凭借它优异的压缩性能迅速占领了市场,从下图可以看到,除了 IE 和 Opera Mini 之外,几乎所有的主流浏览器都已支持 Brotli 算法,因此处于资源占用的考虑,比如说流量,建议启用:
以下操作基于宝塔平台,同样适用于LNMP 等平台,区别于操作目录而已。
下载源码
进入 Nginx 源码目录操作:
# cd /www/server/nginx/src/src/
# git clone https://github.com/google/ngx_brotli.git
# cd ngx_brotli
# git submodule update --init
# cd ..
重新编译
通过 nginx -V
获得原先的编译参数:
# nginx -V
configure arguments: --user=www --group=www --prefix=/www/server/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E
在原先编译参数基础上,在尾巴添加 --add-module=./src/ngx_brotli
# ./configure --user=www --group=www --prefix=/www/server/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-stream --with-stream_ssl_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --add-module=./src/ngx_brotli
......
# service nginx stop
# make && make install
......
配置启用
如果只在某个路径启用,那么在 location
段中添加,某个站点启用,那么在 server
段中添加,要全局启用,则在 http
段中添加。
这里我启用全局:
# vim /www/server/nginx/conf/nginx.conf
......
http
{
......
brotli on; #启用
brotli_comp_level 6; #压缩等级,默认 6,太高的压缩水平可能需要更多的 CPU
brotli_buffers 16 8k; #请求缓冲区的数量和大小
brotli_min_length 20; #指定压缩数据的最小长度,只有大于或等于最小长度才会对其压缩。这里指定 20 字节
brotli_types *; #指定允许进行压缩类型
# brotli_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml text/html application/json image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl image/x-icon image/jpeg image/gif image/png image/bmp;
brotli_static always; #是否允许查找预处理好的、以 .br 结尾的压缩文件,可选值为 on、off、always
brotli_window 512k; #窗口值,默认值为 512k
......
}
......
# nginx -t
nginx: the configuration file /www/server/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /www/server/nginx/conf/nginx.conf test is successful
# service nginx start
访问验证
以上我们已经全局启用了 Brotli 算法,接下来我们验证一下:
> General
Request URL: ***
Request Method: GET
Status Code: 200 OK
Remote Address: ***
Referrer Policy: no-referrer-when-downgrade
>Response Headers
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Content-Encoding: br
Content-Type: text/html; charset=UTF-8
Date: Wed, 27 Jun 2018 03:06:40 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: nginx
Transfer-Encoding: chunked
Vary: Accept-Encoding
可以看到响应头包含了 Content-Encoding: br
字样,而 br
正是 Brotli 流压缩的内容编码类型,可见已成功启用,那么效果如何呢?
访问同一页面:
压缩效果可以说非常明显。
高端玩法
经过实际验证,brotli 和 gzip 可以共存,意味着我们可以对部分基于 Node.js 等会在后台自动 Gzip 的站点,设置优先使用 brotli,所以在网站反代配置里加上如下配置,告知后端:前端不接受 Gzip 编码。
proxy_set_header Accept-Encoding "";
上面说到 IE 浏览器和 Opera Mini 暂不支持 brotli,那么访问时仍然使用 gzip 压缩,禁用的话那就是不压缩了。