Алгоритм Brotli и статическое сжатие

На текущий момент алгоритм Brotli поддерживается значительной долей браузеров. Brotli сжимает лучше, чем gzip. Но скорость при максимальной компрессии настолько низкая, что выигрыш от сжатия контента в полном объеме теряется.

Различия между динамическим и статическим сжатием содержимого:

  • Динамическое сжатие выполняется на лету. Посетитель делает запрос, содержимое сжимается, и сжатый содержимое передаётся посетителю.
  • Статическое сжатие осуществляется на диске ещё до запроса данных. Когда посетитель их запрашивает, предварительно сжатые данные просто читаются с диска.

Проблема динамической компрессии заключается в том, что сервер не может ответить на поступивший запрос, пока выполняется сжатие. Если использовать максимальный уровень сжатия, это может задержать выдачу ответа и сказаться на производительности веб-сайта.

Решением данной проблемы будет статическая компрессия данных. Изучив это руководство, вы научитесь осуществлять статическое сжатие файлов для обеспечения оптимальной производительности.

Как сжимать статический содержимое?

Если вы используете фреймворк Express, то потребуется модуль shrink-ray, который реализует статическое сжатие через встроенный механизм кеширования.

Но на серверах Apache это может быть не так просто. Неофициальный модуль Apache mod_brotli(и даже официальный модуль mod_deflate для gzip) не предлагают функциональность для статического сжатия.

Но вы можете предварительно сжать статический содержимое на диске, а далее изменить сервер так, чтобы он предоставлял предварительно сжатые данные с диска, используя mod_rewrite.

Чтобы предварительно сжать данные вручную, используя бинарное сжатие в bash. Но автоматизация этого процесса при помощи gulp намного более удобна.

Допустим, вы планируете предварительно сжать все файлы HTML, CSS, JavaScript, картинки SVG, используемые в проекте и загружать их из отдельной папки:

const brotliCompress =() => { let src = "src/**/*.{html,js,css,svg}", dest = "dist"; return gulp.src(src).pipe(brotli.compress({ extension: "br",       quality: 11        })).pipe(gulp.dest(dest));};exports.brotliCompress = brotliCompress;

Далее выполняется задача brotliCompress:

gulp brotliCompress

Она сжимает файлы, подходящие по формату(указанному в переменной src), и сохраняет их папке(указанной в переменной dest). Файл styles.css будет переименован в styles.css.br, файл scripts.js станет scripts.js.br и так далее.

Уровень компрессии задается в переменной quality. Ее максимальное значение – 11. Также возможно создание сжатых файлов в формате gzip для браузеров, которые не поддерживают алгоритм Brotli, при помощи команды gulp-gzip. Ее синтаксис похож на gulp-brotli. Максимальный уровень сжатия – 9.

Сейчас необходимо правильно изменить конфигурацию Apache:

# Файлы, сжатые по Brotli<Files *.js.br>    AddType "text/javascript".br AddEncoding br.br</Files><Files *.css.br>    AddType "text/css".br AddEncoding br.br</Files><Files *.svg.br>    AddType "image/svg+xml".br AddEncoding br.br</Files><Files *.html.br>    AddType "text/html" .br AddEncoding br .br</Files>

Вы также можете легко указать gzip-версии файлов для тех браузеров, которые не поддерживают алгоритм Brotli:

# Файлы, сжатые по gzip<Files *.js.gz>    AddType "text/javascript" .gz AddEncoding gz .gz</Files><Files *.css.gz>    AddType "text/css" .gz AddEncoding gz .gz</Files><Files *.svg.gz>    AddType "image/svg+xml" .gz AddEncoding gz .gz</Files><Files *.html.gz>    AddType "text/html" .gz AddEncoding gz .gz</Files>

Сейчас используем модуль mod_rewrite, чтобы установить кодировки заголовков запроса Accept-Encoding и загружать посетителю поддерживаемую версию сжатых данных:

# Включаем mod_rewriteRewriteEngine On# Предоставляем предварительно сжатые данные BrotliRewriteCond %{HTTP:Accept-Encoding} brRewriteCond %{REQUEST_FILENAME}.br -fRewriteRule ^(.*)$ $1.br [L]# Предоставляем предварительно сжатые данные gzipRewriteCond %{HTTP:Accept-Encoding} gzipRewriteCond %{REQUEST_FILENAME}.gz -fRewriteRule ^(.*)$ $1.gz [L]

Сейчас предварительно сжатый по алгоритму Brotli контент будет предоставлен браузерам, которые его поддерживают. Это указано в их заголовках запроса Accept-Encoding. Иным браузерам будет предоставлены gzip-версии.

Как это сказывается на производительности?

Использование статического сжатия повышает быстродействие веб-сайта. Чтобы это доказать, я провел эксперимент. Первоначально тестовый веб-сайт «весил» примерно 900 Кб вместе с несколькими файлами стилей и скриптов, SVG- картинками. Используя sitespeed.io , я провел 50 измерений для каждого из четырех вариантов сжатия контента:

  1. Динамическое сжатие Brotli на уровне 11.
  2. Статическое сжатие Brotli (на том же уровне).
  3. Динамическое сжатие gzip на уровне 9.
  4. Статическое сжатие gzip (на том же уровне).

Разброс в результатах оказался значительным:

Алгоритм Brotli и статическое сжатие

Сравнение времени ответа при разных способах сжатия

Динамическое сжатие Brotli на наивысшем уровне компрессии медленное. Но при предварительном сжатии данных при помощи Brotli мы получаем всю выгоду от небольшого размера файлов.

Различия между динамическим и статическим сжатием при помощи gzip менее заметные. В среднем статическое сжатие способствует сокращению времени ответа.

Замечания и заключение

Статическое сжатие идеально, но не . К примеру, динамически генерируемый содержимое не подходит для статического сжатия.

Что насчёт атак BREACH ? Сжатый контент подвержен им при передаче через HTTPS. Но это будет проблемой только для персональной информации. В этом случае можно оставить HTML-контент не сжатым.

Существует мало причин не применять статическое сжатие. Даже если сервер не поддерживает его, то сжатие запросто реализовать. Улучшите производительность веб-сайта сегодня!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *