# ну и нахуй всё это?
я пердолю (хех, pierdol.ing) свой sccl.cc по оптимизации уже продолжительное время
сначал был переезд с astro на zine - об этом отдельный шитпост. потом впихивание всего в 1 rtt - тут уже навалена глубокая статья.
tldr: сайт ужат до 13kb gzip, грузится одним TCP-пакетом - один round trip на данные.
сайт то летает, но мне хочеца попсовые eightyeightythrityone картинки - сраные маленькие кнопочки, которые все пихают в футер сайта, типа “powered by something”, ссылки на друзьяшек, клубы типа 512kb.club и 14kb.club и т.д., ибо это тупа круто.
но есть нюанс: сайт оптимизирован до одного запроса, а тут дцать баннеров, где каждый по 200++ байт, на каждый отдельный http-запрос…
: нада чота придумывать…
? откуда вообще 88x31
нахуя я пихаю в статьи кусочек истории? это ведь выглядит максимальньо ИИшно блять, никто читать не будет.
формат 88на31 пиксел - эт старейшая традиция веба, всё примерно началось с netscape: в 1996 году они запустили программу “netscape now!” - кнопки которые можно было вставить на сайт чтоб показать что ты юзаешь их бровсер.
потом идею подхватили microsoft со своим internet explorer,
потом geocities для своих пользователей,
потом “best viewed in…”, “powered by…” и т.д.
: из-за browser wars эти кнопки распространились по всегу вебу.
со временем, с нормальными поисковиками все забыли про этот формат, но щас он вновь хайпует.: neocities, indie web revival, всякие клубы (512kb.club, 14kb.club, no-js.club) - у каждого свой баннер, и народ массово ляпит их на сайты.
тута пример таких баннеров - 13051шт с 11011 neocities :expoding_head:
# проблема 67 запросов
обычно баннеры вставляют <img src="..."> и похуй, т.е. примерно так:

каждый баннер, эт отдельный http-запрос, где каждый эт зачастую (если hotlink) полный цикл: DNS lookup (если холодный), TCP handshake, TLS handshake.
: даже если картинка весит всего 200 байт - накладные расходы в десятки раз больше самой картинки.
благо бол-во хотяб не хотлинкает, а хостит баннеры у себя, но даже с локальным хостингом 67 запросов - это дохуя, если включен HTTP/2 и keep-alive, часть расходов амортизируется, но первый setup всё равно есть, да и каждый запрос это задержка.
а у меня сайт жёстко оптимизирован под 1 rtt - я не могу просто взять и добавить 67 запросов, хотя я могу захотеть добавить 67 баннеров…
филососия не позволяет
тем более помимо скорости тут ещё и бонус в виде обхода расиянских ТСПУ - первый пакет не ловится, если влезает в initcwnd.
? чо делать
ясен хуй впихнуть все картинки в тот же 1 rtt не получится - слишком жирно по информации.
инлайнить в HTML тоже не вариант - каждый баннер в base64 добавит ~33% к весу, и я вылечу за initcwnd.
но можно сделать по-другому - собрать все баннеры в один CSS-файл base64 и подгрузить его ОДНИМ запросом - это получится воторй запрос помимо основного, но зато баннеров может быть хоть 100 одиним запросом. да и на деле баннеры это не осовной контент сайта - потому не страшно, что они не влезают в 1rtt. моя филосисия больше про сохранение полной функциональности сайта в рамках 1rtt и т.д.
собсна идея: при билде сайта генератор читает конфиг, фетчит актуальные баннеры (или берёт локал), конвертит в base64, пихает в CSS как background-image.
# моё решение
у мя css генерится при билде сайта, на входе конфиг типа:
{
"badges": [
{
"url": "https://example.com/assets/example.png",
"href": "https://example.com",
"alt": "example.com",
"file": "1.png"
},
{
"href": "https://test.com",
"alt": "test.com",
"local": "../img/test.com",
"file": "2.png"
}
]
}
есть два режима:
url- фетчит баннер с указанного сайтаlocal- берёт локальный файл (если баннер уже скачан и лежит в репе)
генератор обходит конфиг, скачивает/читает файлы, конвертит в base64, генерит css вида:
.badge{display:inline-block;width:88px;height:31px;image-rendering:pixelated;image-rendering:crisp-edges}
.badge-0{background:url(data:image/gif;base64,R0lGODdhWAAfAHcAACH...) no-repeat 0 0}
.badge-1{background:url(data:image/png;base64,iVBORw0KGgoAAAA...) no-repeat 0 0}
/* и так далее */
дальше в html вместо 67 <img> тегов вставляем 67 <a class="badge badge-N"> ссылок с фоновой картинкой из css.
применяется как стиль: 
# profit
вместо 67 отдельных запросов на каждый баннер я получаю:
- основной сайт: 1 http-запрос, 12kb gzip, 1 rtt. // ну это как и было
- Баннеры: 1 http-запрос, один css-файл со всеми картинками в base64.
// если картинок условно меньше 10 - скорее всего css с банерами так же влезет в 14кб, хотя на данном этапе tcp-slow старт уже должен разогнаться, если его не задушит тспу и т.д.

строки “data:” не являются http-запросами - это браузер декодит base64 в картинку локально.
итого:
- ДВА запроса на весь сайт со всеми баннерами. Вместо 68+.
если баннеров станет сильно больше 10 - css-файл может не влезть в один initcwnd и уйти на 2 rtt. Но разница между 1 и 2 rtt не драматична, когда это не основной контент. баннеры в футере - пользователь их всё равно не видит сразу. к тому же у меня есть fallback с кнопочками с буквами без картинки
из минусов:
- base64 добавляет ~33% к размеру бинарных данных, для 88x31 баннеров (обычно < 1kb) это копейки.
- картинки не кешируются отдельно, при обновлении страницы - баннеры грузятся заново вместе с css, но сам css тоже кешируется браузером, т.ч. на практике разница не чувствуется.
- eightyeightthirty.one не заскрапит такие линки
в моём случае профит очевиден: сайт остаётся быстрым, баннеры есть, f12 network страничка в дебагере аккуратная, всё выглядит как надо.
comments