Давайте вместе сжимаемся и узнаем, как Brotli может помочь нам повысить производительность наших веб-сайтов. Я реализовал это в одном из своих рабочих проектов. Так что я просто подумал поделиться своим опытом со всеми.
Основные определения 📖
- Express: быстрый, незамысловатый, минималистичный веб-фреймворк для Node.js.
- Brotli: Это библиотека сжатия данных с открытым исходным кодом, разработанная Юрки Алакуйяла и Золтаном Сабадкой. Он основан на современном варианте алгоритма LZ77, кодировании Хаффмана и контекстном моделировании 2-го порядка.
- Webpack: это сборщик модулей. Он принимает модули с зависимостями и генерирует статические активы, представляющие эти модули.
Начнем с настоящего дерьма !!!
Было два способа реализовать сжатие в Express напрямую (без какого-либо веб-сервера, например, nginx и т. Д.):
- Статическое построение сжатых файлов с помощью Webpack (любого другого средства запуска или построения задач внешнего интерфейса) и их обслуживание по требованию клиента.
- Динамическое построение сжатых файлов во время выполнения (вы можете использовать require (« сжатие )») в express, чтобы динамически сжимать файлы и передавать их клиенту на лету.
Я реализовал только статическое построение файлов. Давайте поговорим об этом подробнее.
Статическое сжатие в Express
На первом этапе, при создании ваших пакетов, вы можете включить эти два плагина: сжатие-webpack-plugin ` и « плагин brotli-webpack `.
const CompressionPlugin = require(‘compression-webpack-plugin’); const BrotliPlugin = require(‘brotli-webpack-plugin’); module.exports = { plugins: [ new CompressionPlugin({ asset: ‘[path].gz[query]’, algorithm: ‘gzip’, test: /\.js$|\.css$|\.html$/, threshold: 10240, minRatio: 0.8 }), new BrotliPlugin({ asset: ‘[path].br[query]’, test: /\.js$|\.css$|\.html$/, threshold: 10240, minRatio: 0.8 }) ] }
Эти плагины будут генерировать файлы gzip и brotli для всех ваших пакетов, т.е. если пакет называется vendor_d0cfe49e718c1366c661.js, вы получите vendor_d0cfe49e718c1366c661.js.gzip и vendor_d0cfe49e718c1366c661. strongjs.br в том же каталоге (предположим, что это тот же каталог) > / dist / static / vendor_d0cfe49e718c1366c661.js. * на данный момент).
PS: Приведенный выше код будет генерировать файлы .gzip и .br только в том случае, если minRatio 0,8 достигается при сжатии файлов. Таким образом, в случае очень маленьких файлов файлы gzip и br не будут сгенерированы. Причина в том, что время сжатия и распаковки обходится дороже, чем фактический файл, обслуживаемый без сжатия.
Вам также может потребоваться установить для общедоступного пути в выходной конфигурации webpack значение «/ static». Он будет указывать общедоступный URL-адрес выходных файлов при ссылке в браузере. Это поможет нам фильтровать URL-адрес запроса и обслуживать файлы с помощью express-static-gzip только static, если URL-адрес состоит из «/ static».
output: { path: '/dist/static', filename: ‘[name]_[chunkhash].js’, chunkFilename: ‘[id].[chunkhash].js’, publicPath: ‘/static/’, },
На втором этапе, который заключается в обслуживании нужного файла на основе входных заголовков из клиентского браузера. Мы будем использовать express-static-gzip
var express = require(“express”); var expressStaticGzip = require(“express-static-gzip”); var app = express(); // app.use(express.static(path.join(__dirname))); This was used previously with express. app.use(“/”, expressStaticGzip(path.join(__dirname), { enableBrotli: true }));
Приведенный выше код является настройкой кода по умолчанию из «express-static-gzip», но я хотел обслуживать только статические файлы из этой библиотеки. Если файл не существует, я хотел выдать ошибку, и мой код не должен идти дальше по другим маршрутам. Итак, я немного взломал исходный код и создал новый файл промежуточного программного обеспечения compress.js.
Ниже взломанный код:
var express = require(“express”); const expressStaticGzip = require(‘compression’); // compression.js gist is available on the github. var app = express(); app.get('*', expressStaticGzip(path.join(__dirname), { urlContains: ‘static/’, fallthrough: false, enableBrotli: true, }));
Я использовал здесь три параметра
- urlContains: он проверит, содержит ли исходный URL-адрес запроса "static /". Тогда обслуживайте файлы только через этот плагин, иначе URL-адрес игнорируется.
- fallthrough: ошибка должна быть ложной, если файл, который вы ищете, не существует в каталоге path.join (__ dirname), а URL-адрес содержит urlContains.
- enableBrotli: он проверит, доступен ли файл Brotli в path.join (__ dirname) и соответствующие заголовки запрашиваются клиентом, а затем обслужит файл .br.
Ниже приводится суть сжатия.js. Я взломал строки 59-65.
Анализ результатов:
Давайте сравним производительность веб-сайта с Brotli или GZip или просто с несжатыми миниатюрными файлами.
В Бога мы верим, все другие приносят данные. -W. Эдвардс Деминг
Давайте углубимся в анализ и найдем действительные числа. Так как это сайт моего рабочего места, который мы использовали для внутренних целей. Я не могу предоставить настоящий снимок экрана здесь, но ниже приведены реальные цифры, которые я собрал при тестировании веб-сайта на различных типах сжатия.
- Brotli на ~ 8% ((7.24–6.67) / 7.24) эффективнее, чем GZIP, и на 65.7% (((19.48–6.67) / 19.48) эффективнее, чем несжатый файл. Если браузер не сможет обслуживать Brotli, у нас есть запасной вариант для gzip, который на 62% ((19,48–7,24) / 19,48) эффективнее несжатого файла. Итак, здесь мы имеем ситуацию Win Win.
- А теперь проанализируем размер. Brotli на ((586–458) / 586) ~ 21,85% эффективен, чем GZIP, и ((2,5 * 1024–458) /2,5 * 1024) ~ 82,1% эффективен, чем несжатые файлы. Так много пропускной способности можно сэкономить, используя сжатие Brotli.
Некоторые данные для медленной сети 3G:
Спасибо всем за то, что дочитали до сих пор. Если вам это нравится и вы хотите, чтобы я написал больше, нажмите 💚, чтобы побудить меня.
PS: Спасибо Kuldeep за помощь в устранении некоторых пробелов и за помощь в устранении сбоев в процессе.