摘要:Brotli与Gzip类似,是构建包压缩算法的一种,本文通过docker实战部署nginx brotli服务,详细说明brotli在web中的应用和效果。
关键词: 大前端 web性能优化 brotli brotli容器化部署 docker
一、目的:
Vue 等MVC框架的前端项目常因框架或第三方包的原因,导致构建包比较大,增加首屏加载时长和用户等待白屏时间,本文介绍Brotli压缩技术在web中的实践,进一步减少构建包大小,提升web网站性能和用户体验。
二、Brotli是什么:
2015 年 9 月 Google 推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率。
三、浏览器的支持:
目前Brotli已经被绝大多数浏览器支持,除IE和Opera Mini浏览器,ios浏览器11版本开始支持,在使用时需注意不支持版本兼容的处理。
四、Brotli与其他压缩算法效果对比:
压缩算法在不同level下的比较(数据摘自网络):
压缩算法对从 Internet 爬网的文档样本的结果,该示例包含 1285 个 HTML 文档:
项目实际情况:
a) 质量级别为11的 Brotli压缩效果明显优于Gzip,压缩率高出 20% ~ 26%。
b) 质量级别为6的Brotli,综合效果最优,其压缩效果、压缩速度、解压速度基本超过Gzip。
c) 质量级别比较高时,其压缩速度明显低于Gzip,不太适合大文件的动态的压缩。
五、docker部署实战:
1、docker容器化部署:
nginx version 1.18.0,Docker version 18.06.1-ce,建议使用nginx1.18版本,低版本不支持动态编译。
// docker nginx 安装
docker pull nginx:1.18.0
docker images nginx
// 启动服务
docker run --name nginx-test -p 9002:80 -d nginx:1.18.0
// 设置关联
mkdir /etc/nginx-test
cd /etc/nginx-test
mkdir log
mkdir www
mkdir config
// id为容器id
docker cp id:/etc/nginx/nginx.conf /etc/nginx-test
docker cp id:/etc/nginx/conf.d/. /etc/nginx-test/config
docker cp id:/usr/share/nginx/html/. /etc/nginx-test/www/
// 删除此容器,在重新起一个
docker stop id
docker ps
docker rm id
docker run --name nginx1.18 -p 9002:80 -v /etc/nginx-test/nginx.conf:/etc/nginx/nginx.conf -v /etc/nginx-test/www/:/usr/share/nginx/html/ -v /etc/nginx-test/log/:/var/log/nginx/ -v /etc/nginx-test/config/:/etc/nginx/conf.d --privileged=true -d nginx:1.18.0
2、生成nginx_brotli编译文件
下载ngx_brotli
// 下载ngx_brotli
git clone https://github.com/google/ngx_brotli.git
// 进入ngx_brotli目录下的deps文件夹,下载brotli
cd /etc/ngx_brotli && git submodule update --init
接下来下载nginx1.18版本注意与docker安装版本一致,否则可能会导致编译的文件无法使用
// 下载nginx1.18
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -xvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
// 编译生成brotli的 .so文件
./configure --with-compat --add-dynamic-module=/etc/ngx_brotli
make modules
// 参数语法:--add-dynamic-module=[模块源码所在目录的绝对路径]
// 查看生成文件
ls objs/*.so
// 输出这个2个文件 objs/ngx_http_brotli_filter_module.so objs/ngx_http_brotli_static_module.so
3、将编译好的模块文件复制到docker nginx关联文件目录下
// 在关联目录www目录下 新建modules目录 放入编译的brotli so文件
sudo cp objs/{ngx_http_brotli_filter_module.so,ngx_http_brotli_static_module.so} /etc/nginx-test/www/modules
4、docker nginx配置
...
// 注册brotli
load_module /usr/share/nginx/html/modules/ngx_http_brotli_filter_module.so;
load_module /usr/share/nginx/html/modules/ngx_http_brotli_static_module.so;
...
http {
...
server {
#listen 80;
listen 443 ssl http2 ; // 注意brotli只支持https协议
server_name 域名;
ssl_certificate /usr/share/nginx/html/cert/elsttest2.sinewave.top.cert.pem;
ssl_certificate_key /usr/share/nginx/html/cert/elsttest2.sinewave.top.key.pem;
location / {
root /usr/share/nginx/html/teacher;
index index.html;
}
// 保留gzip 是为了兼容不支持brotli的浏览器
gzip on;
gzip_buffers 32 4K;
gzip_comp_level 6;
gzip_min_length 100;
gzip_types application/javascript text/css text/xml;
gzip_disable "MSIE [1-6].";
gzip_vary on;
// 配置brotli
brotli on;
brotli_static on;
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript
image/svg+xml application/octet-stream;
}
}
5、前端生成brotli构建包
vue.config.js文件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /.js$|.html$|.css/,
threshold: 2048,
minRatio: 0.8
}),
new CompressionWebpackPlugin({
filename: '[path].br',
algorithm: 'brotliCompress',
test: /.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8,
compressionOptions: {
level: 11,
}
})
)
}
}
6、打包文件至docker>nginx>www>teacher文件下,重启nginx
// id 为容器id
docker ps
docker stop id
docker restart id
验证brotli是否成功
六、项目实际效果评估:
测试环境:
brotli可提升web首屏加载速度20%+,网速越慢构建包越大提升效果越明显,浏览器兼容性良好,建议学习储备。