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

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

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

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

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

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

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

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

Здесь может пригодиться пользовательский словарь с использованием процесса, известного как дельта-сжатие , когда словарь предыдущей версии ресурса можно использовать для сжатия более поздней версии. В предыдущем примере, если вы сжали версию Angular 1.8.3, используя версию 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. Если вы хотите опробовать это на своем рабочем веб-сайте и посмотреть, как сжатие общего словаря может принести пользу реальным пользователям, зарегистрируйтесь для участия в пробной версии Origin , чтобы получить токен, и узнайте, как работают пробные версии Origin .

Заключение

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