Увеличьте эффективность сжатия с помощью общих словарей

Опубликовано: 6 марта 2024 г.

Сжатие данных — это проверенный временем метод оптимизации производительности, который уменьшает размер доступных ресурсов страницы. Долгое время на веб-серверах было распространено использование gzip для сжатия распространенных текстовых ресурсов страниц, таких как HTML, CSS и JavaScript-файлы, и их отправки клиенту для распаковки. В результате обеспечивалась более быстрая загрузка ресурсов без ущерба для предполагаемого поведения страницы.

Хотя gzip сам по себе очень эффективен, в последние годы были достигнуты дальнейшие улучшения в области сжатия веб-данных. В 2016 году в Chrome был внедрен алгоритм Brotli, обеспечивающий в целом лучшие коэффициенты сжатия для соответствующих ресурсов. К концу 2017 года все современные браузеры стали поддерживать Brotli, и поддержка этого алгоритма на серверах стала более распространенной. Совсем недавно Chrome внедрил сжатие ZStandard .

Однако на этом работа не заканчивается! Команда Chrome работала над тем, чтобы сделать общие словари доступными для использования в интернете, и теперь они доступны в пробной версии для Brotli и ZStandard . Общие словари могут дополнять сжатие Brotli и ZStandard, обеспечивая значительно более высокие коэффициенты сжатия для веб-сайтов, которые часто обновляют код, и в некоторых случаях могут достигать 90% и более . В этой статье более подробно рассказывается о том, как работают общие словари и как зарегистрироваться для участия в пробной версии, чтобы использовать их для Brotli и ZStandard на своем веб-сайте. Вы также можете посмотреть это видео:

Объяснение общих словарей

Сжатие — это процесс поиска избыточных последовательностей во входных данных и использования этой информации для создания гораздо меньшего по размеру выходного файла, который впоследствии можно обратить вспять. Сжатие хорошо работает в интернете, поскольку существенно сокращает время загрузки ресурсов. Как Brotli, так и ZStandard могут ещё больше повысить свою эффективность, используя словарь сжатия , представляющий собой набор дополнительных шаблонов, которые эти алгоритмы могут использовать во время сжатия. Фактически, высокая эффективность Brotli в некоторой степени достигается за счёт использования внутреннего словаря.

Однако, с Brotli и ZStandard можно использовать пользовательские словари, содержащие шаблоны, специфичные для конкретных ресурсов. На практике пользовательский словарь представляет собой внешний файл, который можно применить к любому входному файлу. Словари могут быть очень специфичными для производственного кода приложения или, по сути, для любого содержимого. Насколько применим тот или иной словарь к входным данным, может существенно повлиять на общую эффективность сжатия. Словари, которые очень похожи на содержимое входных данных, будут давать результаты с более высоким коэффициентом сжатия, чем словари с общим или непохожим содержимым.

Вот пример того, насколько эффективным может быть пользовательский словарь сжатия: предположим, ваш веб-сайт использует фреймворк Angular, и текущая версия — 1.7.9. Эта версия фреймворка Angular в несжатом виде занимает около 172 КиБ. При сжатии с использованием настроек Brotli по умолчанию её размер уменьшается примерно до 53 КиБ. Это даёт коэффициент сжатия почти 70%. Однако, предположим, вы решите позже обновиться до Angular 1.8.3. Учитывая, что эта версия Angular примерно такого же размера, как и версия 1.7.9, вы можете ожидать практически тот же коэффициент сжатия, что и у предыдущей версии.

Здесь может пригодиться пользовательский словарь, использующий процесс, известный как дельта-сжатие , когда словарь предыдущей версии ресурса может быть использован для сжатия более поздней версии. В предыдущем примере, если бы вы сжали версию 1.8.3 Angular, используя версию 1.7.9 в качестве словаря, размер выходного файла составил бы чуть более 4 КиБ. Это соответствует коэффициенту сжатия почти 98% . Очевидно, что словари сжатия могут оказать большое влияние на производительность загрузки, и их эффективность уже подтверждена в реальных приложениях !

Однако реализация этого подхода в веб-среде сопряжена с трудностями. Суть в том, что если вы используете словарь для сжатия ресурса, вам потребуется тот же словарь для его распаковки . Подобный подход уже применялся в веб-среде — в частности, SDCH — но его безопасная реализация оказалась сложной задачей. Предложенный нами метод сжатия с использованием общего словаря решает эти проблемы, обеспечивая при этом существенные преимущества как для статических, так и для динамических ресурсов.

Как Chrome рекламирует поддержку общих словарей

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

Accept-Encoding: gzip, br, zstd

В этом конкретном заголовке Accept-Encoding указано, что браузер, запрашивающий ресурс, поддерживает алгоритмы сжатия gzip, Brotli и ZStandard. Веб-сервер, отвечающий на запрос, может затем решить, какой алгоритм использовать при обработке запроса.

Когда включена поддержка общих словарей и для ресурса доступен соответствующий словарь, в заголовок Accept-Encoding добавляются дополнительные токены. Эти токены называются br-d для Brotli и zstd-d для Zstandard. Chrome также будет включать хеш доступного словаря, о чем будет рассказано далее.

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

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

Сжатие с использованием общего словаря для статических ресурсов

Статический ресурс страницы — это ресурс, который всегда выдает один и тот же ответ на запрошенный URL. Распространенными примерами сжимаемых статических ресурсов являются файлы JavaScript и CSS. Эти ресурсы обычно версионируются для целей кэширования тем или иным способом — иногда с помощью хеша содержимого файла в имени файла (например, styles.abcd1234.css ) или каким-либо другим методом идентификации ресурса. Эти типы ресурсов отлично подходят для дельта-сжатия, которое обеспечивают общие словари, поскольку статические ресурсы часто кэшируются в течение длительного времени и, как правило, обновляются с определенной частотой.

Словарь можно указать для статического ресурса, задав для него заголовок ответа Use-As-Dictionary . Заголовок принимает одну из нескольких пар ключ/значение, но единственной обязательной является match , которая принимает синтаксис URLPattern , указывающий путь к ресурсу, где должен использоваться словарь:

Use-As-Dictionary: match="/dist/styles.*.css"

Представьте заголовок Use-As-Dictionary как механизм, применяемый к будущим версиям ресурса, соответствующим указанному в нем шаблону. Например, предположим, что все стили вашего веб-сайта находятся в одном CSS-файле. Для простоты предположим, что первая версия этого ресурса находится по адресу /dist/styles.v1.css и отправляется с заголовком ответа Use-As-Dictionary содержащим значение match /dist/styles.*.css .

Спустя некоторое время вы обновляете CSS своего веб-сайта и распространяете новую версию, расположенную по адресу /dist/styles.v2.css . Поскольку значение match , использованное в заголовке ответа Use-As-Dictionary из предыдущей версии, применяется к этому запросу, браузер отправит заголовок Available-Dictionary , содержащий хеш словаря, закодированный в виде структурированной последовательности байтов поля :

Accept-Encoding: gzip, br, zstd, br-d, zstd-d
Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:

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

Если вы часто обновляете код своего веб-сайта, дельта-сжатие может оказаться очень полезным. Однако этот процесс достаточно гибкий. Если браузер не определяет наличие словаря в кэше пользователя, он не будет указывать дополнительные токены br-d или zstd-d в заголовке Accept-Encoding . В этом случае применяется стандартный алгоритм сжатия.

Сжатие с использованием общего словаря для динамических ресурсов

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

В силу особенностей динамически генерируемых ресурсов, словарь необходимо загрузить на стороне клиента для последующего использования. Предварительная загрузка словаря означает, что применение сжатия с использованием общего словаря к динамическим ресурсам носит предположительный характер. В таких случаях предполагается, что ваш веб-сайт получит достаточный трафик, чтобы затраты на словарь можно было амортизировать за счет большого количества посещений. Если вы решите попробовать, первым шагом будет указание местоположения словаря с помощью элемента <link> в HTML-коде вашей страницы:

<link rel="dictionary" href="/dictionary.dat">

Когда Chrome встречает этот элемент <link> , он может загрузить словарь, когда страница находится в режиме ожидания, и с низким приоритетом, чтобы избежать конфликтов с пропускной способностью. Ответ на запрос словаря должен содержать заголовок Use-As-Dictionary и указывать, к какому пути динамического ресурса он применяется:

Use-As-Dictionary: match="/product/*"

Дальнейший процесс в основном аналогичен процессу обработки статических ресурсов. Браузер увидит, что сам словарь относится к соответствующим ресурсам, и добавит к запросу заголовок Available-Dictionary с хешем содержимого словаря, опять же, аналогично процессу обработки статических ресурсов, описанному ранее.

Сжатие статических ресурсов во время сборки.

Если вы знакомы с сборщиками, то, возможно, вам знакомы различные плагины для них, которые могут сжимать ресурсы во время сборки и впоследствии предоставлять эти сжатые ресурсы. Например, Apache позволяет использовать директивы для предоставления предварительно сжатых ресурсов во время запроса.

Большинство сборщиков Node.js, поддерживающих сжатие, используют встроенную в Node библиотеку Zlib. Zlib поддерживает Brotli, и сборщики, использующие её, обычно предоставляют интерфейс для прямой передачи параметров в Zlib, которая поддерживает сжатие с помощью словарей . Вот несколько сборщиков, поддерживающих использование словарей:

Обратите внимание, что доступные словари для любой версии ресурса могут использовать одну из любых предыдущих версий ресурса. Это означает, что вам необходимо анализировать пользовательский трафик и планировать соответствующим образом. Стремитесь к балансу и создавайте ресурсы, которые принесут максимальную пользу максимальному числу возвращающихся пользователей. В настоящее время CDN-провайдеры экспериментируют с сжатием на основе общих словарей. Пока что реализаций для публичного использования нет, но мы ожидаем, что это изменится!

Попробуйте!

Интеграция сжатия с помощью общего словаря с существующими возможностями сжатия браузера потенциально может существенно улучшить скорость загрузки веб-сайтов, которые часто обновляют код и получают значительный трафик от повторных посетителей. Если вы заинтересованы в использовании сжатия с помощью общего словаря, у вас есть два варианта:

  1. Если вы просто хотите самостоятельно поэкспериментировать с сжатием общего словаря, чтобы понять, как это работает, вы можете включить экспериментальную функцию « Сжатие передачи словаря» на странице chrome://flags .
  2. Если вас заинтересовала возможность протестировать это на вашем рабочем веб-сайте и увидеть, как сжатие с помощью общего словаря может принести пользу реальным пользователям, зарегистрируйтесь для участия в пробной версии , чтобы получить токен, и ознакомьтесь с тем , как работают пробные версии .

Заключение

Мы очень рады этому значительному прогрессу в технологии сжатия данных в интернете и тому, насколько быстрее это может ускорить работу существующих приложений, которыми люди пользуются каждый день. Мы призываем вас попробовать это, и, что наиболее важно, мы хотим услышать ваши впечатления ! Если вы обнаружите ошибку, сообщите о ней на crbug.com . Дополнительные ресурсы и инструменты можно найти на use-as-dictionary.com . Наконец, если вас интересует более подробное описание того, как всё это работает, следующий шаг — это объяснение !