此 Codelab 是对缩减和压缩网络载荷
Codelab
并假设您熟悉压缩的基本概念。如
相较于 gzip
等其他压缩算法,此 Codelab 探讨了
Brotli 压缩可进一步降低压缩比,并降低应用的整体性能,
。
测量
在深入研究如何进行优化之前,最好先分析 应用的当前状态。
- 点击 Remix to Edit 以使项目可修改。
- 如需预览网站,请按查看应用。然后按 全屏 。
请参阅上文中的缩减网络载荷大小和
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+I
或
Ctrl+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 大小:
现在,您可以看到从 Content-Encoding
标头中的 bz
应用了 brotli
。
main.bundle.js
从 225 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/
目录。
- 点击工具按钮。
- 点击控制台按钮。
- 在控制台中,运行以下命令以切换到
public
目录并查看其中的所有文件:
cd public
ls -lh
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 面板。
大功告成!您已使用 Brotli 压缩功能进一步压缩了资源!
总结
此 Codelab 说明了 brotli
如何进一步降低应用的整体
。在支持的情况下,brotli
是一种比
gzip
。