使用 brotli 缩减和压缩网络载荷

Michael DiBlasio
Michael DiBlasio

此 Codelab 是对缩减和压缩网络载荷 Codelab 并假设您熟悉压缩的基本概念。如 相较于 gzip 等其他压缩算法,此 Codelab 探讨了 Brotli 压缩可进一步降低压缩比,并降低应用的整体性能, 。

应用屏幕截图

测量

在深入研究如何进行优化之前,最好先分析 应用的当前状态。

  1. 点击 Remix to Edit 以使项目可修改。
  2. 如需预览网站,请按查看应用。然后按 全屏 全屏

请参阅上文中的缩减网络载荷大小和 Codelab, 我们已将 main.js 的大小从 225 KB 缩减至 61.6 KB。在此 Codelab 中,您 将探讨 Brotli 压缩如何进一步缩减此包大小。

Brotli 压缩

布罗特利 这是一种更新的压缩算法, 比gzip的结果。根据 CertSimple,Brotli 的效果为:

  • gzip(对于 JavaScript)小 14%
  • gzip (HTML) 小 21%
  • 对于 CSS 而言,比 gzip 小 17%

要使用 Brotli,您的服务器必须支持 HTTPS。以下语言支持 Brotli: 大多数浏览器的最新版本。浏览器 支持 Brotli 的 Accept-Encoding 头文件中将包含 br

Accept-Encoding: gzip, deflate, br

您可以通过 Content-Encoding 字段(Command+Option+ICtrl+Alt+I):

“网络”面板

启用 Brotli

动态压缩

动态压缩涉及在素材资源生成时实时对其进行压缩 。

优点

  • 创建和更新已保存的压缩版素材资源无需 完成。
  • 实时压缩功能特别适用于 动态生成的图片。

缺点

  • 在较高级别压缩文件以实现更好的压缩比, 。在用户等待素材资源更新时,这可能会导致性能下降 在服务器发送之前对其进行压缩。

使用 Node/Express 进行动态压缩

server.js 文件负责设置用来托管的节点服务器 应用。

var express = require('express');

var app = express();

app.use(express.static('public'));

var listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

目前所做的就是导入 express 并使用 express.static 加载网页中的所有静态 HTML、JS 和 CSS 文件, public/directory(这些文件由 webpack 在每次构建时创建)。

为了确保所有素材资源在每次 请求后,shrink-ray 模块。首先,在 package.json 中将其添加为 devDependency

"devDependencies": {
  //...
  "shrink-ray": "^0.1.3"
},

将其导入服务器文件 server.js

var express = require('express');
var shrinkRay = require('shrink-ray');

在装载 express.static 之前,将其添加为中间件:

//...
var app = express();

// compress all requests
app.use(shrinkRay());

app.use(express.static('public'));

现在重新加载应用,并在 Network 面板中查看 bundle 大小:

使用动态 Brotli 压缩的软件包大小

现在,您可以看到从 Content-Encoding 标头中的 bz 应用了 brotlimain.bundle.js225 KB 减少到 53.1 KB!缩小约 14% 相比之下,gzip (61.6 KB)。

静态压缩

静态压缩背后的理念是先压缩并保存资源 。

优点

  • 高压缩级别导致的延迟不再是问题。没事 需要实时进行压缩文件 。

缺点

  • 每次构建时都需要压缩资源。构建时间可能会增加 如果使用高压缩级别,则会出现明显的差异。

使用 Node/Express 和 webpack 进行静态压缩

由于静态压缩涉及预先压缩文件,因此 webpack 可以在构建步骤中修改设置,以压缩资源。通过 brotli-webpack-plugin 可用于此用途。

首先,在 package.json 中将其添加为 devDependency

"devDependencies": {
  //...
 "brotli-webpack-plugin": "^1.1.0"
},

与任何其他 webpack 插件一样,请将其导入配置文件, webpack.config.js:

var path = require("path");

//...
var BrotliPlugin = require('brotli-webpack-plugin');

并将其包含在 plugins 数组中:

module.exports = {
  // ...
  plugins: [
    // ...
    new BrotliPlugin({
      asset: '[file].br',
      test: /\.(js)$/
    })
  ]
},

插件数组使用以下参数:

  • asset:目标素材资源名称。
  • 系统会将 [file] 替换为原始素材资源文件名。
  • test:与此正则表达式匹配的所有资源(即以 .js)。

例如,main.js 会重命名为 main.js.br

当应用重新加载并重新构建时,系统会生成主软件包的压缩版本 已创建完成。打开 Glitch 控制台,查看最终结果 public/ 目录。

  1. 点击工具按钮。
  2. 点击控制台按钮。
  3. 在控制台中,运行以下命令以切换到 public 目录并查看其中的所有文件:
cd public
ls -lh
使用静态 Brotli 压缩时的软件包大小

app bundle 的 brotli 压缩版本 main.bundle.js.br 现已保存 它们大小约为 76%(相较于 53 KB,大小为 225 KB) main.bundle.js

下一步,指示服务器将 brotli 压缩文件 原始 JS 版本。这可以通过定义新的 在 server.js 中路由,之后通过 express.static 传送文件。

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.br';
  res.set('Content-Encoding', 'br');
  res.set('Content-Type', 'application/javascript; charset=UTF-8');
  next();
});

app.use(express.static('public'));

app.get 用于告知服务器如何GET响应对 特定端点。然后,使用回调函数来定义如何处理 请求。路线的运作方式如下:

  • 指定 '*.js' 作为第一个参数意味着这适用于每个 用于提取 JS 文件而触发的端点。
  • 在回调中,.br 会附加到请求的网址,并且 Content-Encoding 响应标头设置为 br
  • Content-Type 标头设为 application/javascript; charset=UTF-8, 指定 MIME 类型。
  • 最后,next() 可确保序列继续执行任何可能的回调, 下一个。

由于某些浏览器可能不支持 brotli 压缩,因此请确认 brotli 在返回 brotli 压缩文件之前,请先检查 Accept-Encoding 请求标头包含 br

var express = require('express');

var app = express();

app.get('*.js', (req, res, next) => {
  if (req.header('Accept-Encoding').includes('br')) {
    req.url = req.url + '.br';
    console.log(req.header('Accept-Encoding'));
    res.set('Content-Encoding', 'br');
    res.set('Content-Type', 'application/javascript; charset=UTF-8');
  }
  next();
});

app.use(express.static('public'));

应用重新加载后,请再次查看 Network 面板。

捆绑包大小为 53.1 KB(原为 225 KB)

大功告成!您已使用 Brotli 压缩功能进一步压缩了资源!

总结

此 Codelab 说明了 brotli 如何进一步降低应用的整体 。在支持的情况下,brotli 是一种比 gzip