Сайт открывается 6 секунд — где именно теряем время

«Сайт тормозит» — общая жалоба. Конкретные секунды теряются в 5-6 типовых местах: DNS, TLS, TTFB, шрифты, JS, картинки. Разбираем по этапам с реальной разбивкой, что тратит больше всего, и куда смотреть в первую очередь.

«Сайт открывается медленно» — слишком общая жалоба. Чтобы оптимизировать, нужно понимать, где именно теряются секунды. Открываем DevTools, вкладка Network, грузим типовой лендинг с проблемой LCP 6 секунд и смотрим, куда уходит время.

1. DNS-резолв — 50-300 мс

Первый шаг при заходе на сайт. Браузер запрашивает DNS-сервер, получает IP.

Когда проблема:

  • NS-серверы у медленного провайдера — 200-500 мс.
  • DNS не закэширован у пользователя.
  • Несколько уровней CNAME (cdn.example.com → cdn-1234.selcdn.ru → ...).

Решения:

  • NS-серверы у крупного провайдера (Yandex Cloud DNS, Selectel, Cloudflare).
  • Сократить цепочку CNAME.
  • <link rel="dns-prefetch"> для важных внешних доменов.

2. TCP + TLS handshake — 100-400 мс

Установка соединения и шифрование. На современных серверах с TLS 1.3 это:

  • ~50 мс в одной стране через быстрый канал.
  • 200-500 мс через медленный мобильный интернет.

Проблемы и решения:

  • Старый TLS 1.2 → переключите на 1.3.
  • RSA-сертификаты медленнее ECDSA → используйте ECDSA.
  • HTTP/2 или HTTP/3 → меньше handshake'ов для последующих запросов.

3. TTFB — время до первого байта — 100-2000 мс

Самое больное место. Браузер получил соединение, отправил GET, ждёт ответа. Здесь сидит вся обработка на сервере.

Типовые причины долгого TTFB:

  • Медленный PHP без OPcache.
  • Запросы к БД без индексов и кэширования.
  • Сторонние API в синхронном вызове перед рендером HTML.
  • Тяжёлые шаблоны Twig/Smarty без кэша.
  • WordPress с 20 плагинами без object cache.

Решения:

  • Кэширование готового HTML (страничный кэш).
  • Redis для object cache.
  • Перенос сторонних API на async (на фронте через fetch после загрузки).
  • OPcache для PHP всегда.

Цель: TTFB <500 мс. На сильно нагруженных сайтах — <200 мс.

4. CSS — 200-800 мс

Браузер получил HTML, начал парсить, наткнулся на <link rel="stylesheet">. Скачивает, парсит, применяет. До этого рендер блокирован.

Проблемы:

  • Несколько CSS-файлов в head (всё ждёт каждый).
  • CSS на 200-500 КБ с массой неиспользуемых правил.
  • Внешний CSS на разных доменах (новый DNS+TLS на каждый).

Решения:

  • Один минифицированный CSS-файл.
  • Inline critical CSS (первый экран) в head, остальное — async.
  • Удалить неиспользуемые правила (PurgeCSS, Tailwind purge).

5. JavaScript — 500-3000 мс

Самый главный убийца LCP и INP. JS блокирует рендер, главный поток парсит и выполняет.

Проблемы:

  • Большой bundle (1-3 МБ) без code splitting.
  • Скрипты в head без defer.
  • Тяжёлая инициализация (React-приложение на старте).
  • Аналитика (Метрика, Roistat, jivosite) в head синхронно.

Решения:

  • Все скрипты defer или async.
  • Code splitting по маршрутам (если SPA).
  • Аналитика — после события DOMContentLoaded или через requestIdleCallback.
  • Для лендинга — отказ от тяжёлых фреймворков, vanilla JS.
  • Lazy load всего, что ниже первого экрана.

6. Шрифты — 200-1500 мс

Браузер начал рендер, видит @font-face, скачивает шрифт. Без font-display: swap — пустой текст до 3 секунд (FOIT).

Проблемы:

  • Шрифт с Google Fonts (внешний домен).
  • 5-10 начертаний.
  • Без preload.
  • Без font-display: swap или fallback.

Решения:

  • Шрифт локально, WOFF2.
  • 2-3 начертания максимум.
  • preload для основного.
  • font-display: swap.

7. Картинки — 300-3000 мс

Тяжёлые изображения первого экрана задерживают LCP.

Проблемы:

  • JPG/PNG вместо AVIF/WebP — в 3-5 раз тяжелее.
  • Hero-картинка 4 МБ вместо 200 КБ.
  • Без width/height → CLS.
  • Без loading="lazy" для нижних картинок.

Решения:

  • AVIF (или WebP fallback) для всего, кроме первого экрана.
  • <picture> с несколькими source.
  • Размеры в HTML.
  • preload для LCP-картинки.

Реальная разбивка 6 секунд

Типовой лендинг с проблемами:

  • DNS: 250 мс.
  • TLS handshake: 200 мс.
  • TTFB: 1200 мс (WordPress без кэша).
  • HTML parsing: 50 мс.
  • CSS download + parse: 700 мс (два файла, без минификации).
  • JS download: 1800 мс (React-обёртка + аналитика).
  • JS execution: 900 мс.
  • Шрифты с Google Fonts: 600 мс.
  • Hero-картинка: 600 мс.

Итого ~6 сек.

После оптимизации

  • DNS: 50 мс (dns-prefetch).
  • TLS: 100 мс (TLS 1.3, ECDSA).
  • TTFB: 200 мс (страничный кэш Redis).
  • HTML parsing: 50 мс.
  • CSS: 150 мс (inline critical, async остальное).
  • JS: 200 мс (defer, code splitting).
  • Шрифты: 150 мс (локально, preload).
  • Картинка: 250 мс (AVIF, preload).

Итого ~1.2 сек. Снижение в 5 раз.

Где смотреть

  • DevTools → Network → таблица timing.
  • DevTools → Performance → flame chart.
  • PageSpeed Insights → Diagnostic + Opportunities.
  • WebPageTest → Waterfall + Filmstrip.

Вывод

6 секунд складываются из 7 этапов, каждый со своим вкладом. Главные убийцы — TTFB (медленный сервер), JS (тяжёлые bundle), шрифты с внешнего домена, нелёгкие картинки. Оптимизация по этим 4 пунктам снижает время в 3-5 раз без переписывания сайта.

Узнайте подробнее о наших компетенциях
Разработка, ИИ, автоматизация — что мы делаем и как.