Методы сжатия данных в Сети: zopfli, brotli, sdch

Рассмотренные в статье «продвинутые» механизмы сжатия данных являются проверенными временем практиками и могут быть использованы в рабочем веб-окружении прямо сегодня.

Быстрый сайт — это почти всегда сайт, небольшой по размеру. Чем меньше будет объем данных, который браузеру или поисковому роботу нужно загрузить для получения сайта, тем быстрее сайт отобразится или попадет в поисковый индекс. В предыдущей статье мы подробно рассмотрели поточное (gzip) сжатие как наиболее используемый метод уменьшения размера передаваемых данных. Но кроме него существуют еще несколько методов, которые, благодаря инициативам Google, уже можно использовать для большинства пользователей.

Zopfli

Zopfli является инициативой инженеров Google по созданию более эффективного алгоритма LZ-сжатия, который бы работал лучше существующих аналогов и был обратно совместим с gzip-распаковкой. Для этого в дополнение к потоковым методам сжатия (с максимально допустимым окном кодирования) используются энтропийные методы (кодирование Хаффмана и поиск минимального представления), что в совокупности дает выигрыш в размере 5-7% на реальных данных.

Это можно проиллюстрировать на следующем примере. Если у нас есть строка «CCCCDDDABABABCCCCABABAB», то ее LZ-представление будет выглядеть примерно следующим образом: C{4,1}D{3,4}AB{4,7}C{4,11}AB{4,15}. Где в скобках указаны пары длина-начало кодируемого сегмента. При этом стандартный gzip создаст словарь по мере нахождения совпадающих подстрок: в словаре C будет обозначено в битах 1, D – 01, AB – 001.

Алгоритм zopfli пересортирует словарь по частоте вхождения подстрок, и обозначит в битах C – 1, AB – 01, D – 001. Таким образом, на все указанное выше представление строки удастся сэкономить 1 бит при использовании zopfli (те самые 5-7% от «стандартного» размера).

Платой за более высокую степень сжатия (чем gzip-9) является крайне медленная работа алгоритма (приходится строить полное частотное дерево сжимаемой информации, что является трудоемкой процедурой). Zopfli работает (в зависимости от настроек) в 30-100 раз медленнее gzip. Это ограничивает область его применения только статическим сжатием.

Как применить zopfli

Поскольку сжатые zopfli файлы можно распаковать как обычные gzip-архивы (ведь они таковыми и являются — наиболее оптимальным представлением gzip-архива для заданного файла), то его можно использовать для создания готовых gz-файлов (сжатых версий) CSS и JavaScript (а случае полностью статического сайта — и HTML) ресурсов.

Zopfli уже интегрирован в большинство пакетов, для сборки его на вашем сервере достаточно выполнить следующие команды:

git clone https://code.google.com/p/zopfli/

cd zopfli

make

chmod +x zopfli

./zopfli -c <FILENAME> > <FILENAME.gz>

Для применения статического сжатия нужно не забыть его включить в вашем веб-сервере. Для nginx это одна директива (при наличии модуля gzip_static):

gzip_static on;

Brotli

После разработки более эффективной версии gzip инженеры из Google не остановились. Следующим шагом была создание отдельного алгоритма сжатия данных, который сжимал данные лучше, но не сильно проигрывал в скорости gzip. Таким алгоритмом стал brotli. В нем сложились все три блока методов сжатия: поточное, энтропийное и словарное.

Brotli использует собственный словарь (составляющий 2/3 от самого спецификации алгоритма) из почти 100 тысяч различных фраз и кусочков слов, наиболее часто встречающихся в Сети. Этот словарь применяется как основа для поточного сжатия данных (как в LZ-кодировании), но не исключает добавление новых строк, найденных в сжимаемом тексте. И, конечно, brotli использует энтропийное сжатие для наименьшего представления полученного архива.

Фактически, в браузеры, поддерживающие brotli, уже встроен почти весь словарь, используемый при сжатии данных, и он в архиве не передается. За счет этого и достигается значительный выигрыш в размере архивов.

Максимальная степень сжатия — 11 — позволяет добиться на 25% меньшего размера файла по сравнению с gzip-9, и на 20% - по сравнению с zopfli. По времени сжатия brotli примерно сравним с zopfli, но с большим отличием: малая степень сжатия по скорости чуть-чуть уступает gzip, а степень сжатия при равной скорости существенно больше. Максимальная степень сжатия медленнее gzip-9 примерно в 80-100 раз.

Все браузеры на основе Chrome, Firefox и Edge 15 уже поддерживают brotli (но делают это только для SSL-соединений), на уровне HTTP-заголовков это выглядит так:

Accept-Encoding: br

Как использовать brotli

Для включения в nginx поддержки brotli необходимо собрать, как минимум, модуль brotli_static и включить его в конфигурации:

brotli_static on;

В таком режиме nginx будет при получении от браузера соответствующего заголовка (что brotli поддерживается) проверять, есть ли файл с расширением .br рядом с запрашиваемым — и отдавать его как сжатый brotli-архив.

Для создания самих brotli-архивов нужно будет либо установить из репозитория, либо отдельно собрать утилиты bro:

git clone https://github.com/badger/libbrotli

cd libbrotli

autoreconf -i

make install

git clone https://github.com/google/brotli

cd brotli

./configure

make

chmod +x bro

./bro --quality 11 --input <FILENAME> --output <FILENAME.br>

Можно дополнительно включить brotli-сжатие «на лету», установив модуль nginx brotli, но это может привести к дополнительным издержкам CPU при отгрузке страниц пользователям и ботам.

Для подключения brotli для IIS необходимо установить отдельный модуль: IIS Brotli, а для Apache есть mod_brotli, который настраивается аналогичным образом:

LoadModule brotli_module modules/mod_brotli.so

<IfModule brotli_module>

AddOutputFilterByType BROTLI text/html text/plain text/css text/xml

BrotliCompressionLevel 10

BrotliWindowSize 22

</IfModule>

SDCH

От «швейцарского ножа» сжатия в Сети (brotli) переходим к более узкому инструменту — VCDIFF, или более известному как SDCH-сжатие. VCDIFF предполагает использование заранее определенного словаря (который должен быть передан пользователю) и реализуется в браузерах через протокол SDCH (который является просто «оберткой» поверх VCDIFF контейнеров с данными).

Плюсом SDCH является то, что это альтернативный вариант сжатия, который можно использовать в дополнение к gzip или brotli: запаковать страницу при помощи SDCH-словаря, а запакованную версию дополнительно сжать «на лету», браузеры так понимают.

Минусом является достаточно сложный подготовительный процесс: необходимо создать словарь на основе нескольких страниц сайта, который будет содержать наиболее часто используемые блоки (чтобы передать их один раз) и не будет слишком большим (иначе будет «дешевле» передать сами страницы без SDCH-сжатия). Ниже показан примерный выигрыш в размере при использовании SDCH.

Очевидно, что если пользователь просматривает более 3 страниц на сайте — то выигрыш от использования этого алгоритма будет. Если меньше — то можно ограничиться стандартными механизмами сжатия. Детально механизм подключенияописан в блоге Айри, кратко алгоритм выглядит следующим образом:

1. Нужно установить пакет femtozip для сборки словаря из наиболее характерных страниц сайта.

2. Нужно установить VCDIFF библиотеки на сервер для использования словаря при кодировании «на лету».

3. Нужно установить модуль nginx sdch для кодирования «на лету».

4. Нужно собрать словарь при помощи femtozip и дополнительно сжать его zopfli или brotli.

5. Нужно включить sdch-сжатие «на лету» для сайта в конфигурации nginx на базе собранного словаря.

В качестве заключения

Все рассмотренные «продвинутые» механизмы сжатия данных в Сети являются проверенными временем практиками (реализованными в соответствующих модулях и библиотеках) и могут быть использованы в рабочем веб-окружении прямо сегодня.

При дополнительной настройке веб-сервера возможно сокращение размера передаваемых текстовых данных еще на 25-70% (brotli / scdh), что может быть серьезным преимуществом для новостных порталов и высоконагруженных проектов, где на счету каждые 100 мс времени загрузки сайта. Даже обычное использование zopfli для сжатия статических файлов уже даст выигрыш в 5-7%, которые могут помочь вам сделать сайт быстрее.

preview Как повлиять на скорость индексирования сайта в поиске Яндекса

Как повлиять на скорость индексирования сайта в поиске Яндекса

Помимо работы с новым сайтом, (о которой было рассказано в предыдущей статье) большое количество вопросов в поддержку поступает о работе с уже проиндексированным ресурсом
preview ROI для SEO: Как правильно измерять эффективность органического трафика

ROI для SEO: Как правильно измерять эффективность органического трафика

Как быть с «инвестированием» в SEO? Разве это не «бесплатный» трафик? Как можно определить ценность чего-то, что не имеет цены...
preview Оценка эффективности SEO. Чек-лист для владельца бизнеса

Оценка эффективности SEO. Чек-лист для владельца бизнеса

Если мы что-то делаем, то это должно давать результат. Результат в SEO-продвижении – это трафик и продажи...
preview «Ключ+год»: ещё один способ получить трафик по конкурентным запросам

«Ключ+год»: ещё один способ получить трафик по конкурентным запросам

В одном из последних выпусков Whiteboard Friday Рэнд Фишкин предложил несложную тактику, которая позволяет продвигаться в условиях жёсткой конкуренции с помощью очень свежего...
preview 5 советов по A/B-тестированию на 2017 год

5 советов по A/B-тестированию на 2017 год

Начало года – важное время для бизнеса. В этот период компании пересматривают свои подходы к работе и составляют планы на текущий год...
preview SEO без хэппи-энда

SEO без хэппи-энда

О чем эта история? О том, что SEO - это совместная работа подрядчика и заказчика...