Эта лаборатория является расширением лаборатории по минимизации и сжатию сетевых полезных данных и предполагает, что вы знакомы с основными концепциями сжатия. По сравнению с другими алгоритмами сжатия, такими как gzip
, в этой лаборатории кода показано, как сжатие Brotli может еще больше уменьшить коэффициент сжатия и общий размер вашего приложения.
Мера
Прежде чем приступить к оптимизации, всегда полезно сначала проанализировать текущее состояние приложения.
- Нажмите Remix to Edit , чтобы сделать проект доступным для редактирования.
- Чтобы просмотреть сайт, нажмите «Просмотреть приложение» . Затем нажмите Полноэкранный режим .
В предыдущей лаборатории по минимизации и сжатию сетевых полезных данных мы уменьшили размер main.js
с 225 КБ до 61,6 КБ. В этой лаборатории вы узнаете, как сжатие Brotli может еще больше уменьшить размер этого пакета.
Компрессия Бротли
Brotli — это новый алгоритм сжатия, который может обеспечить даже лучшие результаты сжатия текста, чем gzip
. Согласно CertSimple , производительность Brotli составляет:
- На 14 % меньше, чем
gzip
для JavaScript. - На 21 % меньше, чем
gzip
для HTML. - На 17 % меньше, чем
gzip
для CSS.
Чтобы использовать Brotli, ваш сервер должен поддерживать HTTPS. Brotli поддерживается в последних версиях большинства браузеров . Браузеры, поддерживающие Brotli, будут включать br
в заголовки Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Вы можете определить, какой алгоритм сжатия используется, с помощью поля Content-Encoding
на вкладке «Сеть инструментов разработчика Chrome» ( Command+Option+I
или Ctrl+Alt+I
):
Включение Бротли
Динамическое сжатие
Динамическое сжатие предполагает сжатие ресурсов «на лету» по мере их запроса браузером.
Плюсы
- Создавать и обновлять сохраненные сжатые версии ресурсов не требуется.
- Сжатие «на лету» особенно хорошо работает для веб-страниц, которые генерируются динамически.
Минусы
- Сжатие файлов на более высоких уровнях для достижения лучшей степени сжатия занимает больше времени. Это может привести к снижению производительности, поскольку пользователь ожидает сжатия ресурсов, прежде чем они будут отправлены сервером.
Динамическое сжатие с помощью Node/Express
Файл server.js
отвечает за настройку сервера Node, на котором размещается приложение.
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
(и эти файлы создаются веб-пакетом при каждой сборке).
Чтобы убедиться, что все ресурсы сжимаются с использованием brotli каждый раз, когда они запрашиваются, можно использовать модуль shrink-ray
. Начните с добавления его как devDependency
в package.json
:
"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'));
Теперь перезагрузите приложение и посмотрите на размер пакета на панели «Сеть»:
Теперь вы можете видеть, brotli
применяется из bz
в заголовке Content-Encoding
. main.bundle.js
уменьшен с 225 КБ до 53,1 КБ ! Это примерно на 14% меньше по сравнению с gzip
(61,6 КБ).
Статическое сжатие
Идея статического сжатия заключается в предварительном сжатии и сохранении ресурсов.
Плюсы
- Задержка из-за высокого уровня сжатия больше не является проблемой. Для сжатия файлов ничего не нужно делать «на лету», поскольку теперь их можно получить напрямую.
Минусы
- Ресурсы необходимо сжимать при каждой сборке. Время сборки может значительно увеличиться, если используются высокие уровни сжатия.
Статическое сжатие с помощью Node/Express и веб-пакета
Поскольку статическое сжатие предполагает предварительное сжатие файлов, настройки веб-пакета можно изменить для сжатия ресурсов на этапе сборки. Для этого можно использовать brotli-webpack-plugin
.
Начните с добавления его как devDependency
в package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
Как и любой другой плагин веб-пакета, импортируйте его в файл конфигурации webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
И включите его в массив плагинов:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
Массив плагина использует следующие аргументы:
-
asset
: имя целевого актива. -
[file]
заменяется исходным именем файла ресурса. -
test
: обрабатываются все ресурсы, соответствующие этому RegExp (то есть ресурсы JavaScript, оканчивающиеся на.js
).
Например, main.js
будет переименован в main.js.br
Когда приложение перезагружается и перестраивается, теперь создается сжатая версия основного пакета. Откройте консоль Glitch, чтобы посмотреть, что находится внутри последнего каталога public/
, обслуживаемого сервером Node.
- Нажмите кнопку «Инструменты» .
- Нажмите кнопку Консоль .
- В консоли выполните следующие команды, чтобы перейти в
public
каталог и просмотреть все его файлы:
cd public
ls -lh
Версия пакета, сжатая Brotli, main.bundle.js.br
, теперь также сохраняется здесь и имеет размер примерно на 76% меньше (225 КБ против 53 КБ), чем 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
прикрепляется к URL-адресу запроса, а заголовку ответа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'));
После перезагрузки приложения еще раз взгляните на панель «Сеть».
Успех! Вы использовали сжатие Brotli для дальнейшего сжатия своих ресурсов!
Заключение
В этой кодовой лаборатории показано, как brotli
может еще больше уменьшить общий размер вашего приложения. Если поддерживается, brotli
является более мощным алгоритмом сжатия, чем gzip
.