Brotli 运用实践总结

介绍

BrotliGoogle 推出的开源压缩算法,通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率,性能也比我们目前常见的 Gzip 高17-25%,可以帮我们更高效的压缩网页中的各类文件大小及脚本,从而提高加载速度,提升网页浏览体验。需要说明的是 Brotli 压缩只在 https 下生效,因为 在 http 请求中 request header 里的 Accept-Encoding: gzip, deflate 是没有 br 的。

Brotli 如此高的压缩比率,得益于其使用一个预定义的字典,该字典包含超过 13000 个来自文本和 HTML 文档的大型语料库的常用字符串,预定义的算法可以提升较小文件的压缩密度,而压缩与解压缩速度则大致不变。

Brotli 凭借它优异的压缩性能迅速占领了市场,从下图可以看到,除了 IEOpera Mini 之外,几乎所有的主流浏览器都已支持 Brotli 算法,因此处于资源占用的考虑,比如说流量,建议启用:

image-20210525084609637

服务器端配置

本示例中使用的相关资源如下

  • 操作系统:Ubuntu 20.04
  • Nginx 版本:nginx/1.18.0

安装配置 git

在安装之前请先确定当前服务器是否安装 git,装配置好 git,请直接进入下一步骤。
安装 git

sudo apt-get install git
复制代码

下载 Brotli

google/ngx_brotli 从 16年12月的版本起,开始内置google/brotli,所以我们不需要额外编译 bagder/libbrotli 库,让安装变得简单起来。
我们将 google/ngx_brotli 下载并解压到 /usr/local/src/ngx_brotli 目录

cd /usr/local/src
sudo git clone https://github.com/google/ngx_brotli.git || sudo git clone https://github.com.cnpmjs.org/google/ngx_brotli.git
复制代码

然后在下载 google/brotli 并解压到 /usr/local/src/ngx_brotli/deps/brotli

cd /usr/local/src/ngx_brotli/deps && rm -rf brotli
git clone https://github.com/google/brotli.git || sudo git clone https://github.com.cnpmjs.org/google/brotli.git
cd /usr/local/src/ngx_brotli && git submodule update --init
复制代码

下载解压 Nginx 源码包

请下载与当前 Nginx 版本相同的 Nginx 源码包。Nginx 官方下载地址:nginx.org/en/download…

可通过命令,获取当前 Nginx 版本:

nginx -v
复制代码

输出:

nginx version: nginx/1.18.0 (Ubuntu)
复制代码

下载并解压 Nginx 源码包:

cd /usr/local/src
sudo wget http://nginx.org/download/nginx-1.18.0.tar.gz
sudo tar -xvf nginx-1.18.0.tar.gz
复制代码

编译动态模块

cd nginx-1.18.0
sudo ./configure --with-compat --add-dynamic-module=/usr/local/src/ngx_brotli
sudo make modules
复制代码

参数语法:–add-dynamic-module=[模块源码所在目录的绝对路径]

等运行完成后,查看编译好的模块:

ls objs/*.so
复制代码

输出:

objs/ngx_http_brotli_filter_module.so  objs/ngx_http_brotli_static_module.so
复制代码

将编译好的模块文件复制到 Nginx 动态模块加载目录:

sudo cp objs/{ngx_http_brotli_filter_module.so,ngx_http_brotli_static_module.so} /etc/nginx/modules
复制代码

注册 Brotli 模块

修改 Nginx 配置文件 nginx.conf

cd /etc/nginx
sudo vim nginx.conf
复制代码

可以在头部添加:

# Brotli 模块
load_module /etc/nginx/modules/ngx_http_brotli_filter_module.so;
load_module /etc/nginx/modules/ngx_http_brotli_static_module.so;
复制代码

启动 Brotli 压缩

Brotligzip 是可以并存的,因此无需关闭 gzip

sudo vim nginx.conf
复制代码
http{
    ...
    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_static on;
    gzip_disable "MSIE [1-6]\.";
    gzip_min_length 1k;
    gzip_vary on;
    gzip_comp_level 3;
    gzip_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;

    ##
    # Brotli Settings
    ##

    brotli on;
    brotli_static on;
    brotli_comp_level 6;
    brotli_buffers 16 8k;
    brotli_min_length 20;
    brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml application/xml+rss application/json image/jpeg image/gif image/png;
	...
}
复制代码

验证 Nginx 配置是否正确并重启 Nginx

sudo nginx -t
sudo systemctl reload nginx
复制代码

清理临时文件

要养成好习惯,每次编译完后都要把应用包解压出来的文件或目录进行删除。

rm -rf /usr/local/src/{nginx-1.18.0/,ngx_brotli/}
复制代码

前端配置

vue-cli 中配置

修改 vue.confi.js 文件:

const CompressionWebpackPlugin = require('compression-webpack-plugin') // 压缩插件
 
configureWebpack: config => {
    const plugins = [
      ......
      // gzip 压缩
      new CompressionWebpackPlugin({
        filename: '[path][base].gz',
        algorithm: 'gzip',
        test: new RegExp(
          '\\.(' +
          ['js', 'css'].join('|') +
          ')$'
        ),
        threshold: 10240,
        minRatio: 0.8
      }),
      // brotli 压缩
      new CompressionWebpackPlugin({
        filename: '[path][base].br',
        algorithm: 'brotliCompress',
        test: /\.(js|css|html|svg)$/,
        threshold: 10240,
        minRatio: 0.8
      })
    ]
    if (process.env.NODE_ENV === 'production') {
      config.plugins = [...config.plugins, ...plugins]
    }
  },
复制代码

vite 中配置

修改 vite.config.ts 文件

import viteCompression from 'vite-plugin-compression' // 压缩插件

  // 插件
  plugins: [
    ...
    // gzip 压缩 
    viteCompression({
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'gzip',
      ext: '.gz'
    }),
    // brotli 压缩  
    viteCompression({
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'brotliCompress',
      ext: '.br'
    })
  ],
复制代码

验证压缩是否生效

curl 验证

curl -H 'Accept-Encoding: br' -I http://localhost
复制代码
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 24 May 2021 14:38:29 GMT
Content-Type: text/html
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"5e9efe7d-264"
Content-Encoding: br
复制代码

浏览器端验证

未开启:

image-20210524224107752

已开启

image-20210524224138018

参考文献

  1. Nginx启用Brotli压缩
  2. Nginx 为站点启用 Brotli 压缩算法
  3. gzip,zopfli及brotli压缩对比,vue配置及服务端实现
  4. Nginx开启Google Brotli压缩
  5. How to install Brotli Module for Nginx on Ubuntu 20.04
  6. compression-webpack-plugin
  7. vite-plugin-compression
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享