Запрос дошёл до сервера. В первой части от момента «запрос отправлен» до первого байта ответа прошло 310 мс — больше, чем все сетевые шаги вместе. Здесь разберём обратную дорогу: что делает сервер, пока браузер ждёт, сколько из этого можно не делать вовсе и что браузер делает с полученным HTML. Спойлер: самое большое ускорение — не в сети.

Это одиннадцатая часть цикла «Что происходит, когда открываешь сайт».

Что происходит на сервере

У этого сайта путь запроса внутри сервера такой: прокси принимает TLS и передаёт запрос в nginx, nginx смотрит в кэш страниц. Если готовая копия есть — отдаёт её сразу. Если нет — передаёт PHP: WordPress загружается, делает запросы к базе, собирает HTML из шаблонов, и только потом ответ уходит обратно.

Сравним оба пути на одной странице. Для сборки «с нуля» добавляем к адресу параметр, который кэш пропускает мимо:

$ curl … https://alekseychikun.ru/blog/                  # из кэша
tls=0.125068 ttfb=0.159290   x-cache-status: HIT
tls=0.099590 ttfb=0.134298   x-cache-status: HIT

$ curl … "https://alekseychikun.ru/blog/?nocache=…"     # мимо кэша
tls=0.124027 ttfb=0.323557   x-cache-status: BYPASS
tls=0.109751 ttfb=0.267440   x-cache-status: BYPASS

Вычитаем время конца TLS из времени первого байта — получаем, сколько ждали ответа на сам запрос:

ПутьОжидание ответаИз него сеть
из кэша34–35 мс29 мс — один круг
сборка PHP158–200 мс29 мс, остальное — работа сервера
35 мс ~170–200 мс: PHP собирает страницу TCPTLSответ Сеть и шифрование одинаковы. Разница — только в том, готова ли страница заранее. из кэша (HIT)сборка (BYPASS)
Один и тот же запрос с готовой страницей и без неё.

Из кэша сервер тратит на ответ около 6 мс — почти всё ожидание составляет дорога туда и обратно. Сборка — 130–170 мс работы, и это на лёгкой странице блога. У интернет-магазина с фильтрами и ценами из базы та же сборка легко занимает секунду и больше.

Вот почему мы так много пишем о кэше страниц. Ни сеть, ни протокол, ни настройки TLS не дают такого выигрыша: разница между HIT и сборкой больше, чем вся сетевая часть запроса.

Ответ поехал: 8,8 КБ за один круг

Сжатая страница — 8,75 КБ. Это меньше начальной порции TCP (около 14 КБ, пятая часть), поэтому весь HTML уходит одним залпом, без ожидания подтверждений. Если бы страница весила 200 КБ, понадобилось бы ещё несколько кругов, пока TCP разгоняется. Лёгкий HTML — это не про трафик, а про число кругов.

HTML — только начало

Получив HTML, браузер не показывает страницу сразу. Он читает его сверху вниз и находит, что ещё нужно загрузить. На странице блога этого сайта:

ЧтоСколько
таблицы стилей4
скрипты4
картинки в разметке10
шрифты, загружаемые заранее (preload)2
ссылок на сторонние домены1 — счётчик статистики

Все ресурсы со своего домена браузер запрашивает по тому же соединению HTTP/2 — новое рукопожатие не нужно. А для стороннего домена всё начинается сначала: DNS, TCP, TLS — ещё 100–200 мс, прежде чем придёт первый байт. Поэтому каждый внешний сервис на странице — счётчик, шрифты, виджет — стоит не только своего веса, но и нового соединения. И поэтому счётчик на этом сайте загружается не сразу, а после первого действия посетителя.

Что блокирует отрисовку

  • стили в <head> браузер ждёт обязательно: без них не нарисовать ни одного пикселя правильно;
  • скрипты без defer или async останавливают разбор HTML, пока не скачаются и не выполнятся;
  • шрифты — текст может ждать шрифт до трёх секунд, если не задано font-display: swap;
  • картинки отрисовку не блокируют, но первая крупная картинка часто и есть то, что посетитель ждёт увидеть.

Всё это — уже не сеть, а фронтенд: что и в каком порядке страница просит загрузить. Как это мерить и разгонять, подробно разобрано в нашем цикле про PageSpeed.

Где на самом деле уходит время — сводка

ШагХолодный заходЧто помогает
DNS36 мскэш резолвера; разумный TTL
TCP28 мсkeep-alive, одно соединение HTTP/2
TLS128 мсключ ECDSA, возобновление сессий
сервер130–270 мскэш страниц — до 6 мс
передача HTML1 кругсжатие, лёгкий HTML
подресурсыот сотен мсменьше сторонних доменов, defer, preload

Сервер отвечает долго, а почему — неясно?

Пришлите адрес — сравню ответ из кэша и без него и покажу, куда уходят миллисекунды на сервере.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.