Передача словаря сжатия
Передача словаря сжатия
Ограниченная доступность
Эта функция не входит в Baseline, поскольку не работает в некоторых наиболее широко используемых браузерах.
Хотите, чтобы эта функция поддерживалась лучше? Расскажите нам почему.
Экспериментальная функция: Это экспериментальная технология
Перед использованием в рабочей среде внимательно ознакомьтесь с таблицей совместимости с браузерами.
Передача словаря сжатия — это способ использовать общий словарь сжатия для значительного уменьшения размера HTTP-ответов при передаче.
Обзор
В HTTP используются алгоритмы сжатия, чтобы уменьшить размер ресурсов, загружаемых по сети, сократив расход трафика и время загрузки страниц. Алгоритмы сжатия HTTP без потерь работают, находя избыточность в исходных данных: например, участки, где повторяется текст вроде строки "function". Затем они сохраняют только одну копию повторяющейся строки, а все её вхождения в ресурсе заменяют ссылками на эту копию. Поскольку ссылки короче строки, сжатая версия получается меньше.
Примечание: Предыдущая попытка реализовать эту технологию называлась SDCH (Shared Dictionary Compression for HTTP), но она так и не получила широкую поддержку и была удалена в 2017 году. Передача словаря сжатия — это более подробно специфицированная и надёжная реализация, основанная на более широком отраслевом консенсусе.
Например, возьмём этот JavaScript:
function a() {
console.log("Hello World!");
}
function b() {
console.log("I am here");
}
Его можно сжать, заменив повторяющиеся строки ссылками на предыдущее расположение и количество символов, например так:
function a() {
console.log("Hello World!");
}
[0:9]b[10:20]I am here[42:46]
В этом примере [0:9] означает копирование 9 символов, начиная с символа 0. Обратите внимание, что это упрощённый пример, демонстрирующий концепцию; реальные алгоритмы гораздо сложнее.
После загрузки клиенты могут выполнить обратное преобразование и восстановить исходный несжатый ресурс.
Словари сжатия
Алгоритмы, такие как сжатие Brotli и сжатие Zstandard, обеспечивают ещё большую эффективность, позволяя использовать словари часто встречающихся строк, так что их копии не нужно включать в сжатый ресурс. Эти алгоритмы поставляются с предопределённым словарём по умолчанию, который используется при сжатии HTTP-ответов.
Передача словаря сжатия развивает эту идею, позволяя предоставить собственный словарь, особенно подходящий для определённого набора ресурсов. При сжатии и распаковке ресурса алгоритм сжатия может использовать его как источник байтов.
Если предположить, что ссылки из предыдущего примера включены в этот общий словарь, размер можно ещё больше уменьшить:
[d0:9]a[d10:20]Hello World![d42:46] [d0:9]b[d10:20]I am here[d42:46]
Словарь может быть отдельным ресурсом, необходимым только для передачи словаря сжатия, или ресурсом, который веб-сайту нужен и без того.
Например, предположим, что на вашем сайте используется библиотека JavaScript. Обычно вы загружаете определённую версию библиотеки и можете включить название версии в имя библиотеки, например <script src="my-library.v1.js">. Когда браузер загружает вашу страницу, он получает копию библиотеки в качестве подресурса.
Если затем вы обновите библиотеку до версии v2, большая часть её кода, вероятно, останется прежней. Поэтому сайты могут значительно уменьшить размер загрузки my-library.v2.js, указав браузеру использовать my-library.v1.js в качестве словаря сжатия для my-library.v2.js. Тогда строки, общие для v1 и v2, не нужно включать в загрузку v2, поскольку они уже есть в браузере. Таким образом, большая часть загружаемого my-library.v2.js будет представлять собой лишь разницу между двумя версиями.
Передача словаря сжатия может обеспечить сжатие на порядок эффективнее, чем сжатие с использованием встроенного словаря по умолчанию. Примеры реальных результатов приведены в разделе Примеры передачи словаря сжатия.
Формат словаря
Для словаря сжатия не предусмотрен какой-либо определённый формат или конкретный MIME-тип. Это обычные файлы, которые можно использовать для сжатия других файлов с похожим содержимым.
Предыдущие версии файлов обычно содержат много похожего контента, поэтому они отлично подходят в качестве словарей. Использование предыдущей версии файла как словаря позволяет алгоритму сжатия эффективно ссылаться на всё неизменившееся содержимое и сохранять только относительно небольшие различия в новой версии. Такой подход называется дельта-сжатием.
Другой вариант — перечислить часто встречающиеся строки (например, шаблоны HTML) в новом файле dictionary.txt, чтобы использовать его для сжатия HTML-страниц сайта. Этот подход можно дополнительно оптимизировать с помощью специализированных инструментов, например генератора словарей Brotli, который уменьшает словари до минимального размера с минимальным перекрытием.
Словари также можно использовать для эффективного сжатия двоичных форматов. Например, двоичные файлы WASM — это большие ресурсы, которым также может быть полезно дельта-сжатие.
Существующий ресурс в качестве словаря
Чтобы использовать ресурс в качестве словаря, сервер должен включить заголовок Use-As-Dictionary в ответ, содержащий этот ресурс:
Use-As-Dictionary: match="/js/app.*.js"
Значение этого заголовка указывает ресурсы, которые могут использовать данный ресурс в качестве словаря: в этом случае сюда входят все ресурсы, URL которых соответствует заданному шаблону.
Когда позднее запрашивается ресурс, соответствующий заданному шаблону (например, app.v2.js), запрос будет содержать SHA-256-хеш доступного словаря в заголовке Available-Dictionary, а также значения dcb и/или dcz в заголовке Accept-Encoding (для дельта-сжатия с использованием Brotli или ZStandard, соответственно):
Accept-Encoding: gzip, br, zstd, dcb, dcz Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=:
Затем сервер может отправить ответ с соответствующей кодировкой, указанной в заголовке Content-Encoding:
Content-Encoding: dcb
Если ответ можно кэшировать, он должен содержать заголовок Vary, чтобы кэши не отправляли ресурсы, сжатые с помощью словаря, клиентам, которые его не поддерживают, и не отправляли ответ, сжатый с помощью неподходящего словаря:
Vary: accept-encoding, available-dictionary
В заголовке Use-As-Dictionary также можно указать необязательное значение id, чтобы серверу было проще найти файл словаря, если он не хранит словарь по его хешу:
Use-As-Dictionary: match="/js/app.*.js", id="dictionary-12345"
Если это значение указано, оно будет передаваться в последующих запросах в заголовке Dictionary-ID:
Accept-Encoding: gzip, br, zstd, dcb, dcz Available-Dictionary: :pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=: Dictionary-ID: "dictionary-12345"
Сервер всё равно должен проверять хеш из заголовка Available-Dictionary — Dictionary-ID предоставляет серверу дополнительные сведения для идентификации словаря, но не заменяет заголовок Available-Dictionary.
Отдельный словарь
HTML-документ также может предоставить браузеру словарь сжатия, который не является ресурсом, загружаемым браузером и без того, например через элемент <script>. Для этого есть два способа:
-
Добавить элемент
<link>с атрибутомrel, которому присвоено значениеcompression-dictionary:<link rel="compression-dictionary" href="/dictionary.dat" />
-
Указать словарь с помощью заголовка
Link:Link: </dictionary.dat>; rel="compression-dictionary"
После этого браузер загрузит словарь во время простоя, а ответ должен содержать заголовок Use-As-Dictionary:
Use-As-Dictionary: match="/js/app.*.js"
Далее процесс аналогичен предыдущему примеру, когда запрашивается соответствующий ресурс.
Создание ответов, сжатых с помощью словаря
В ответах, сжатых с помощью словаря, можно использовать алгоритмы Brotli или ZStandard, при этом необходимо выполнить ещё два требования: добавить магический заголовок и встроенный хеш словаря.
Ресурсы, сжатые с помощью словаря, можно создавать динамически, но для статических ресурсов лучше подготовить их заранее, на этапе сборки. При использовании предыдущих версий в качестве словарей необходимо решить, сколько версий с дельта-сжатием создавать: только для последней версии или для последних X версий, где X — некоторое значение.
Для файла словаря с именем dictionary.text и файла для сжатия с именем data.text следующая команда Bash сожмёт файл с помощью Brotli и создаст сжатый файл с именем data.txt.dcb:
echo -en '\xffDCB' > data.txt.dcb && \ openssl dgst -sha256 -binary dictionary.txt >> data.txt.dcb && \ brotli --stdout -D dictionary.txt data.txt >> data.txt.dcb
Для тех же входных файлов следующая команда Bash сожмёт файл с помощью ZStandard и создаст сжатый файл с именем data.txt.dcz:
echo -en '\x5e\x2a\x4d\x18\x20\x00\x00\x00' > data.txt.dcz && \ openssl dgst -sha256 -binary dictionary.txt >> data.txt.dcz && \ zstd -D dictionary.txt -f -o tmp.zstd data.txt && \ cat tmp.zstd >> data.txt.dcz
Обратите внимание: помимо Brotli или ZStandard, локально должен быть установлен OpenSSL.
Ограничения
Алгоритмы сжатия подвержены риску атак, поэтому для передачи словаря сжатия предусмотрен ряд ограничений, в том числе:
- Словари должны иметь тот же источник, что и ресурс, использующий словарь.
- Ресурсы, сжатые с помощью словаря, должны иметь тот же источник, что и документ, либо соответствовать правилам CORS; поэтому их нужно запрашивать с атрибутом
crossoriginи отдавать с соответствующим заголовкомAccess-Control-Allow-Origin. - На словари распространяется стандартное разделение HTTP-кэша, поэтому их нельзя использовать совместно между источниками, даже если те загружают одинаковые ресурсы. Для каждого источника словарь потребуется загружать заново.
Кроме того, сами словари могут стать средством отслеживания, поэтому браузеры могут ограничивать эту функцию, когда файлы cookie отключены или включены дополнительные средства защиты конфиденциальности.
Как и для других ресурсов, если сайт использует заголовок Content-Security-Policy, словарь сжатия должен быть разрешённым источником, чтобы его можно было загрузить. В частности, при загрузке отдельного словаря с помощью <link rel="compression-dictionary"> директива connect-src (или default-src, если connect-src не задана) должна разрешать расположение словаря.
Спецификации
| Спецификация |
|---|
| Неизвестная спецификация> |
Совместимость с браузерами
>html.elements.link.rel.compression-dictionary
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Accept-Encoding.dcb
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Accept-Encoding.dcz
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Available-Dictionary
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Content-Encoding.dcb
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Content-Encoding.dcz
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Dictionary-ID
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
http.headers.Use-As-Dictionary
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari для iOS | Samsung Internet | WebView Android | WebView для iOS | |
Compression_dictionary_transport |
130 | 130 | Нет | 115 | Нет | 130 | Нет | 86 | Нет | 28.0 | 130 | Нет |
См. также
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Compression_dictionary_transport