Compression dictionary transport
Как мы обычно доставляем ассеты пользователям? Ну, добавляем хешик на основе контента к названию файла. Юзер его скачивает. Потом меняем одну строчку, а юзер снова скачивает ассет целиком размером в 200кб.
А что если можно по другому?
Я недавно упомянал Brotli в контексте CI, но если посмотреть на сжатие в браузерах, то у нас не так много вариантов, а точнее два: Gzip постарше и Brotli помоложе и эффективней.
Одна из идей, которая бротли делает эффективней — статический словарь. Секрет в том, что есть некий стандартный набор строк, который встречается на каждом сайте: например
Но на деле общее пересечение среди всех сайтов небольшое, на одном текст/джаваскрипт далеко не уедешь.
Здесь то и начинается пост: а что если мы научим сервер отправлять только дифф для ассетов?
Идея выглядит так:
1. Пользователь заходит на сайт и браузер делает запрос за ассетом
2. Сервер отвечает ассетом с заголовками
3. Бразуер кеширует ассет
4. Во время следующего билда генерируется delta-compressed словарь для main.js — т.е. берётся разница между ассетами, для этой разницы генерируется Brotli словарь и соханяется под
5. Пользователь снова заходит на сайт, но браузер делает запрос за
6. Браузер матчит запрос на основе заголовка
7. Сервер отвечает словарем, полученым на 4 шаге, в котором хранится разница между билдами, и заголовками
Как итог, в повторный визит скачивается только та самая разница в виде
Сложно сказать, когда оно появится в браузера, но ребята из хрома высказали желание реализовать эксперимент (более того, в ишью есть инфа о том, что похожая фича была доступна 7 лет назад).
Ишью с идеей: https://github.com/WICG/proposals/issues/90
Детальное разъяснение: https://github.com/WICG/compression-dictionary-transport
P.S. Честно, сложновато рассказывать о том, в чём сам так себе разбираешься, так что рекомендую, как обычно, сходить по ссылкам. Там умные люди всё за меня расписали. Так же я без понятия как проводят инициативы в WICG, так что какие-то прогнозы по срокам писать не берусь.
Как мы обычно доставляем ассеты пользователям? Ну, добавляем хешик на основе контента к названию файла. Юзер его скачивает. Потом меняем одну строчку, а юзер снова скачивает ассет целиком размером в 200кб.
А что если можно по другому?
Я недавно упомянал Brotli в контексте CI, но если посмотреть на сжатие в браузерах, то у нас не так много вариантов, а точнее два: Gzip постарше и Brotli помоложе и эффективней.
Одна из идей, которая бротли делает эффективней — статический словарь. Секрет в том, что есть некий стандартный набор строк, который встречается на каждом сайте: например
type=“text/javascript”
и используя общий словарь, мы экономим байты на передаче этой информации.Но на деле общее пересечение среди всех сайтов небольшое, на одном текст/джаваскрипт далеко не уедешь.
Здесь то и начинается пост: а что если мы научим сервер отправлять только дифф для ассетов?
Идея выглядит так:
1. Пользователь заходит на сайт и браузер делает запрос за ассетом
static.example.com/app/main.js/123
с заголовком Accept-Encoding: sbr,br,gzip
, где 123 — скажем, порядковый номер пайплайна2. Сервер отвечает ассетом с заголовками
use-as-dictionary: p="/app/main.js"
и Vary: Accept-Encoding,
sec-available-dictionary
3. Бразуер кеширует ассет
/app/main.js
и его хеш-сумму SHA-256
4. Во время следующего билда генерируется delta-compressed словарь для main.js — т.е. берётся разница между ассетами, для этой разницы генерируется Brotli словарь и соханяется под
main.js.<hash>.sbr
5. Пользователь снова заходит на сайт, но браузер делает запрос за
static.example.com/app/main.js/124
, т.к. мы раздаём новый билд6. Браузер матчит запрос на основе заголовка
use-as-dictionary
и делает новый запрос с Accept-Encoding: sbr,br,gzip
и sec-available-dictionary: <SHA-256 HASH>
, который сохранился на 3 пункте7. Сервер отвечает словарем, полученым на 4 шаге, в котором хранится разница между билдами, и заголовками
Content-Encoding: sbr
и Vary: Accept-Encoding,
sec-available-dictionary
Как итог, в повторный визит скачивается только та самая разница в виде
main.js.<hash>.sbr
с 4 шага и распаковывается, а если пользователь зашёл впервые, то ассет отдаётся как обычно.Сложно сказать, когда оно появится в браузера, но ребята из хрома высказали желание реализовать эксперимент (более того, в ишью есть инфа о том, что похожая фича была доступна 7 лет назад).
Ишью с идеей: https://github.com/WICG/proposals/issues/90
Детальное разъяснение: https://github.com/WICG/compression-dictionary-transport
P.S. Честно, сложновато рассказывать о том, в чём сам так себе разбираешься, так что рекомендую, как обычно, сходить по ссылкам. Там умные люди всё за меня расписали. Так же я без понятия как проводят инициативы в WICG, так что какие-то прогнозы по срокам писать не берусь.