Сервер, TTFB и кеширование: скорость до того, как началась вёрстка
Highlights
Заголовок раздела «Highlights»- Половина проблем со скоростью решается до того, как речь зайдёт о вёрстке и картинках. Если сервер думает секунду, оптимизация фронтенда этого уже не отыграет.
- Ориентир по TTFB от web.dev: до 0,8 секунды — хорошо, больше 1,8 — плохо. Сам по себе TTFB не входит в Core Web Vitals, но он предшествует LCP и служит для него потолком.
- Кеш — самый дешёвый прирост скорости из существующих. Одно включённое кеширование страниц на тяжёлой CMS часто даёт больше, чем неделя работы над фронтендом.
- Сжатие обязательно, но не всё подряд: brotli и gzip дают эффект на тексте, а на уже сжатых форматах вроде JPEG и WebP только тратят процессор.
- HTTP/2 полезен людям, но ранжирующего бонуса у него нет, и Googlebot одинаково спокойно ходит по HTTP/1.1 и HTTP/2.
- По HTTP/3 Googlebot не ходит вообще. Внедрять его стоит ради пользователей, а не ради робота, и точно не вместо поддержки более старых протоколов.
- Медленный сервер бьёт по обходу. Google снижает частоту сканирования, если сайт отвечает медленно или отдаёт ошибки, и повышает, когда всё быстро.
- Чаще всего сайт тормозят не его собственные файлы, а чужие: аналитика, чат-виджет, пиксели рекламных кабинетов и виджеты соцсетей.
- Первое, что нужно понять при разборе — где именно теряется время. Одинаковые пять секунд на бэкенде и на картинках лечатся совершенно по-разному.
Разговор про скорость сайта обычно начинается не с того конца. Открывают PageSpeed Insights, видят красное, идут сжимать картинки и минифицировать CSS. Иногда помогает. Но регулярно оказывается, что браузер полсекунды просто ждёт, пока сервер соизволит ответить, и вот эти полсекунды не убрать никакой минификацией — они потрачены до того, как браузер получил хоть один байт.
Поэтому я всегда начинаю с разделения: сколько времени уходит до первого байта и сколько после. Это два разных мира с разными подрядчиками, разными инструментами и разной стоимостью работ.
Из чего складывается ответ
Заголовок раздела «Из чего складывается ответ»Слева — то, за что отвечают хостинг, сервер и сеть. Справа — то, за что отвечает фронтенд. Инструменты вроде PageSpeed показывают общую картину, но разбирать проблему надо по этим двум половинам отдельно, иначе получается лечение симптомов.
TTFB: сколько это в цифрах
Заголовок раздела «TTFB: сколько это в цифрах»Time to First Byte — время от начала запроса до момента, когда пришёл первый байт ответа. В него входят редиректы, поиск DNS, установка соединения с TLS-рукопожатием и, главное, работа самого бэкенда.
Пороги web.dev простые: до 0,8 секунды хорошо, от 0,8 до 1,8 — есть над чем работать, больше 1,8 — плохо. Отдельно оговорено, что TTFB не входит в Core Web Vitals, то есть формально держаться в зелёной зоне не обязательно.
На это стоит смотреть трезво. TTFB не метрика ранжирования, но он потолок для всего остального: LCP физически не может случиться раньше, чем пришёл первый байт. Если TTFB полторы секунды, то уложить LCP в рекомендованные 2,5 почти нереально — на всю отрисовку остаётся секунда. Так что TTFB чинят не ради самого TTFB, а ради Core Web Vitals и живых людей.
Что тормозит бэкенд
Заголовок раздела «Что тормозит бэкенд»Синяя часть на схеме — обычно самая жирная и самая дешёвая в исправлении. Типичные причины по частоте:
Страница собирается заново на каждый запрос. Тяжёлая CMS с десятками плагинов на каждый заход выполняет сотни запросов к базе, чтобы собрать ровно ту же страницу, что и минуту назад. Лечится кешем страниц, и это самая большая разовая победа, которую можно получить.
База данных. Запросы без индексов, выборки «на всякий случай» всего каталога, счётчики просмотров, которые пишут в таблицу на каждый заход. На небольшом сайте незаметно, на нагруженном — определяющий фактор.
Соседи по хостингу. На дешёвом шаред-хостинге вы делите процессор с сотней других сайтов. Сервер может отвечать нормально ночью и втрое медленнее вечером, и никакая оптимизация кода это не поправит.
Внешние вызовы в момент отдачи страницы. Когда бэкенд при генерации страницы ходит в чужой API — за курсом валют, остатками на складе, отзывами, — вы наследуете чужую скорость и чужие сбои. Такие вызовы надо кешировать или уносить в фон.
Редиректы. Каждый лишний переход в цепочке добавляется к TTFB целиком. Ещё одна причина схлопывать цепочки, помимо тех, что описаны в статье про коды состояния HTTP.
Кеширование на трёх уровнях
Заголовок раздела «Кеширование на трёх уровнях»Кеш — это ответ на вопрос «зачем делать заново то, что уже сделано». Уровней три, и они не заменяют друг друга.
Кеш на сервере. Готовый HTML сохраняется и отдаётся следующим посетителям без обращения к базе. Сюда же — объектный кеш и кеш скомпилированного кода. Главный вопрос здесь не «включить или нет», а «что и на сколько»: страницы каталога кешируются надолго, корзина и личный кабинет не кешируются вообще, а страницы с ценами должны сбрасываться при изменении цены, а не по таймеру через сутки.
Кеш браузера. Управляется заголовком Cache-Control и решает, будет ли повторный визит бесплатным. Рабочая схема: статике с хешем в имени файла (app.4f2b9c.js) ставим срок в год и immutable, а HTML не кешируем надолго, иначе люди будут видеть старую версию сайта. Хеш в имени решает проблему обновления: поменялся файл — поменялся адрес.
Кеш на границе сети (CDN). Копии файлов лежат на серверах ближе к пользователю. Для проекта с географически разбросанной аудиторией это самый заметный выигрыш, потому что сокращает физическое расстояние, а его никаким кодом не сократишь. Если вся ваша аудитория в одном городе, эффект будет скромнее.
Текстовые файлы — HTML, CSS, JavaScript, JSON, SVG — сжимаются в разы. Brotli делает это лучше gzip при сопоставимой скорости, gzip остаётся универсальным запасным вариантом. Настраивается один раз на уровне сервера и дальше просто работает.
Чего делать не надо: сжимать то, что уже сжато. JPEG, PNG, WebP, AVIF, видео и архивы прогонять через brotli бессмысленно — размер не изменится, а процессорное время потратится. У любого нормального сервера есть список типов для сжатия, и в нём должны быть только текстовые форматы.
Проверить просто: в инструментах разработчика в заголовках ответа должен быть content-encoding: br или gzip. Если его нет — вы прямо сейчас отдаёте людям файлы в несколько раз больше нужного.
Протоколы и соединение
Заголовок раздела «Протоколы и соединение»Здесь много фольклора, поэтому по фактам.
HTTP/2 позволяет передавать много файлов по одному соединению и избавляет от старых костылей вроде склейки всех скриптов в один файл. Googlebot ходит по HTTP/2 с конца 2020 года, но Google прямо говорит, что ранжирующего преимущества у этого нет — роботу всё равно, по какому протоколу забирать страницу. Включать стоит ради пользователей.
HTTP/3 работает поверх QUIC и заметно лучше себя ведёт на нестабильных мобильных сетях. Важная деталь, которую стоит знать перед внедрением: Googlebot по HTTP/3 не сканирует. Это не аргумент против — людям он полезен, а на Core Web Vitals может повлиять положительно, — но это аргумент за то, чтобы не отключать поддержку старых протоколов ради него.
Соединение со сторонними доменами. Каждый чужой домен на странице — это отдельный поиск DNS, отдельное соединение и отдельное TLS-рукопожатие. Если сторонний ресурс критичен для первого экрана, помогает preconnect. Но лучший способ не платить за соединение — не делать его вовсе.
Хостинг: когда виноват тариф
Заголовок раздела «Хостинг: когда виноват тариф»Иногда правильный ответ — не оптимизировать, а переехать. Признаки, что дело в хостинге, а не в сайте: TTFB плавает в зависимости от времени суток, простая статическая страница отдаётся так же медленно, как тяжёлая, в панели видны упоры в лимиты процессора, а поддержка на вопросы отвечает предложением перейти на тариф подороже.
Проверяется грубо, но надёжно: положите на сервер обычный HTML-файл без CMS и замерьте время ответа. Если голая статика отдаётся за 600 мс, дело не в вашем коде.
Сторонние скрипты
Заголовок раздела «Сторонние скрипты»Отдельная категория, потому что это скорость, которую вы добавили себе сами. Счётчики аналитики, чат поддержки, пиксели рекламных кабинетов, виджеты соцсетей, карты, формы обратного звонка, всплывающие окна с согласием на куки. По отдельности каждый весит немного. Вместе они часто превосходят вес всего остального сайта.
Что с этим делать: раз в квартал открывать список загружаемых скриптов и спрашивать по каждому, кто им пользуется и когда последний раз смотрел эти данные. Обычно половину можно снять без потерь. Остальное — грузить асинхронно и по возможности после взаимодействия, а не в момент открытия страницы.
Почему это важно не только для людей
Заголовок раздела «Почему это важно не только для людей»Скорость сервера влияет на обход напрямую. Google формирует лимит сканирования исходя в том числе из состояния сайта: отвечает быстро — лимит растёт, начинает тормозить или отдавать ошибки — лимит снижается. То есть медленный сервер означает не только раздражённых посетителей, но и то, что новые страницы будут попадать в индекс дольше. Механика подробно разобрана в статье про краулинговый бюджет.
И ещё одна связь, о которой забывают: затяжные 5xx в часы нагрузки — это не «сайт немножко полежал». Для поисковика это сигнал, что сайту нездоровится, и при повторении он начинает выбрасывать страницы из индекса.
Как измерять
Заголовок раздела «Как измерять»Полевые данные против лабораторных. Замер на вашем ноутбуке по быстрому проводу показывает лучший случай. Реальность видна в отчёте Search Console по Core Web Vitals и в CrUX — там данные живых визитов, включая мобильный интернет в метро.
Разложение по фазам. Вкладка Network в инструментах разработчика показывает время ожидания ответа отдельно от времени загрузки. Смотреть надо именно на разбивку, а не на итоговую цифру.
Простая проверка из командной строки. curl -w "%{time_starttransfer}" -o /dev/null -s <адрес> покажет время до первого байта без всякого фронтенда. Прогоните несколько раз в разное время суток — увидите, стабилен ли ваш хостинг.
Логи сервера. Если в них пишется время генерации страницы, вы увидите не средние показатели, а конкретные медленные URL. Обычно выясняется, что тормозит не весь сайт, а три типа страниц.
Чек-лист
Заголовок раздела «Чек-лист»- TTFB на основных типах страниц укладывается в 0,8 секунды.
- Кеширование страниц на сервере включено, динамические страницы из него исключены.
- Кеш сбрасывается по событию (изменилась цена, вышел материал), а не только по таймеру.
-
Cache-Controlдля статики с хешем в имени — длинный срок иimmutable. - HTML не закеширован в браузере надолго.
- Включено сжатие brotli или gzip для текстовых форматов и не включено для картинок и видео.
- Сайт работает по HTTP/2 или новее, поддержка старых протоколов не сломана.
- Цепочек редиректов перед выдачей страницы нет.
- Внешние API не вызываются синхронно при генерации страницы.
- Список сторонних скриптов пересматривался за последние полгода.
- Проверена реальная скорость на полевых данных, а не только в лаборатории.
-
5xxпод нагрузкой отсутствуют, есть внешний мониторинг доступности.
Глубже по теме
Заголовок раздела «Глубже по теме»- Обзор слоя: техническая оптимизация.
- Core Web Vitals — что происходит после первого байта и какие пороги у метрик.
- Анализ Core Web Vitals в реальном времени — как снимать полевые данные.
- Краулинговый бюджет и анализ логов — как скорость влияет на частоту обхода.
- Коды состояния HTTP — про редиректы и ошибки сервера.
- JavaScript SEO — если основное время уходит на выполнение скриптов.
- Первоисточники: TTFB на web.dev и Googlebot и HTTP/2.
- Назад к карте цикла: продвижение сайта.