Почему 14 KB?
Вот в пример реальные запросы.
Вот сайт который влезает в 14кб:

А вот который не влезает:

Download - это и есть контент сайта. 1 ms против 63 ms - разница скорости в 63 раза, при разнице веса всего 7 раз.
TCP Slow Start
Ебуий TCP не выплюнет контент одним пакетом. Даже когда сервер готов ответить - TCP говорит: “погоди братуха, у нас congestion control”:
Он начинает с initcwnd - 10 сегментов (RFC 6928) - это 1460байт.
- Сервер послал 14 KB - ждёт ACK,
- Пришёл ACK - окно удвоилось до 20 сегментов (~29кб),
- Послал теперь 29KB - снова ждёт…
И так пока не передаст всё.
Каждый луп - это RTT, соответсвенно чем больше ответ (наш контент), тем больше rounds. Если ответ влазит в 14.6 KB - он улетает одним пакетом.
Без ожидания && без удвоения && без лишних RTT.
:: One round trip.
На больших файлах (картинки и прочий тяжелый контент) эта особенность уже не доставляет проблем, т.к. tcp успевает разогнаться. Но в бол-ве случаев на сайтах файлы меньше 100кб - и это уже реальная проблема.
И это при условии что у тебя всего один запрос. А если отдельно шрифты, скрипты, картинки - каждый из них проходит полный круг. Одна страница тянет 5-10-20 последовательных запросов, и каждый жрёт время на общение протоколов, а не передачу полезных данных.
В качестве очень плохого примера - сайт New-York Times - 891 http запрос на 9мб контента, 6 секунд blocking time, хотя сайт - буквально стандартный газетный layout, где ничего тяжелого быть не может.
Клубы
Есть 14KB Club - сайты до 14 KB сырыми. Там считают uncompressed size, т.е. по сути туда не пустят сайт, что весит условные 20-30кб, но благодаря сжатию gzip может уместиться в 1rtt, и в реальности будет уступать несжатому сайту на 50-200 ns (наносекунд).
512KB Club - не влезать сюда - ебейшее неуважение к пользователям и к интернету в целом. Удаляйте свой сайт нахуй.
данный бугурт не относится к полезной информации на сайте, по типу фото-видео
Мои потуги
Есть у меня сайтец sccl.cc. Запилен он на Zine - SSG на Zig. Три страницы: contacts, projects, peripherals.
Исходно сервер отдавал:
- HTML (~15kb)
- Space Mono, Martian Mono woff2 (~40kb)
- Аватарка png (~2mb)
- Фавикон png (~1mb)
на скрине уже немного заоптемайзенный, было хуже :skull:
(до переезда на zine был ваще 150+кб, см Migration-from-Astro-to-Zine.md)
Четыре запроса на страницу, на контент, который суммарно нихрена не весит.
Всё это с учётом что полный setup (DNS + TCP + TLS) происходит один раз (keep-alive, HTTP/2). Но даже так - на каждую вкладку, на каждый переход с другой страницы - новый setup.
Оптимизация
План: всё в один HTML. Base64 инлайн всего, ноль внешних запросов. И чтоб влезало в initcwnd.
Шрифт
Это самое жирное, что было на сайте:
У меня было 2 шрифта, в придачу к которым отдельно качались жирные их версии, что в сумме и давало целых 40кб
По-хорошему вообще кастомные шрифты нахуй не нужны в бол-ве ситуаций, но мне очень захотелось уступить эстетике и таки оставить один, выкинув из самого файла шрифта всё кроме ASCII символов, которые реально юзаются на сайте.
Итог: 4.2кб, которые в base64 превратились в 5.7кб текста в HTML.
Аватарка
Инишиал был ультра жирныч, хоть это и пиксельарт, но зарендерен в 400% разрешении.
После прохода через шаколизатор - кортинка сначал была ужата до трёх цветов, что в PNG по прежнему весила целых 1.9кб. Но сконвертив в WebP удалось получитьь 702b.
Base64 → 940b.
Фавиконка
Те же манипуляции, что и с авой - получилось 199b, но осталась в png, т.к. для столь маленьких картинок он лучше работает.
268b в base64.
JS
Тут можно было люто резать, т.к. реально бесполезных скриптов созданных для красоты - у меня навалом. Но мне все же хотелось сохранить весь функционал на сайте, потому всё это говно пошло в inline.
У меня там и анимированные кнопки, анимированный фон и пасхалска с анимацией - всё в сумме весит около 4кб, без которых сайт и так отлично бы работал.
Итог
До: 4 запроса, ~50kb суммарно
После: 1 запрос, 12kb gzip / 27kb raw
Влезает в initcwnd: Один TCP-пакет - один round trip на данные.

Дилемма
Инлайн всего - это компромисс.
При переходе на другую страницу браузер качает тот же шрифт по новой - шрифт внутри HTML, он не кешируется отдельно. С отдельным файлом шрифт закешировался бы после первого раза, и вторую страницу качал бы без него.
Так же стоит учитывать что инлайн обычно весит чуть больше чем внешняя зависимость, и если мы и так не лезем в initcwnd - то и инлайн нам ненужен.
Пример
1. Всё в одном HTML (base64 шрифты)
- 2 страницы по 14кб каждая
- каждая грузится за 1 round trip
- но каждый раз жрёшь полные 14кб, даже если шрифт повторяется
2. HTML + отдельный шрифт
- 2 страницы по 8кб + шрифт 4кб отдельно
- первый заход: 2 запроса (HTML + шрифт)
- переход между страницами: только 8кб (шрифт закеширован)
В реальном интернете разницы между скоростью загрузки 14кб и 8кб - не почувствовать.
А делеи между пакетами - да.