Технический аудит скорости сайта: что чинить первым, если LCP 12,5 секунды

Аудит скорости сайта по замерам: LCP 12,5 с, вес 11 505 КиБ, восемь PNG на 9 086 359 Б, сжатие отсутствует. Аудит по слоям, порядок починки и приёмка.

Коротко: скорость сайта — это не «медленный хостинг», а цепочка из четырёх измеримых вещей: вес страницы, HTTP-сжатие, размер изображений и момент, когда браузер может нарисовать главный объект. В замере реального коммерческого сайта Largest Contentful Paint составил 12,5 секунды при норме ≤ 2,5 с, а TTFB при этом был 0 мс: сервер отвечал мгновенно, и всё время терялось уже после ответа — на скачивании 774 КиБ JavaScript одним файлом, двух запросах к сторонним шрифтам с блокировкой отрисовки на 2 580 мс и восьми PNG-файлах галереи весом 9 086 359 Б. Порядок починки в таких аудитах почти всегда обратный интуиции: сначала сжатие и вес, потом данные и только в конце — переписывание кода. Ниже — как устроен аудит скорости по слоям, что в нём ловят прямые замеры, чего не показывает Lighthouse, и как принимать работу, чтобы не обмануть себя.

Почему «виноват сервер» — почти всегда неверная гипотеза

Начинают аудит всегда не с кода, а с замера в одинаковых условиях: мобильная эмуляция (у нас это Moto G Power), движок Lighthouse 13.5.0, ограничение сети «4G с низкой скоростью», полный отчёт сохраняется — текстом и скриншотом. Разница между «померить у себя на ноутбуке по оптоволокну» и «померить на среднем телефоне в 4G» в этом проекте — семикратная по LCP, и именно она определяет, что чинить.

Что показал замер: производительность 57 из 100 при цели ≥ 90, LCP 12,5 с, First Contentful Paint 7,9 с, Speed Index 7,9 с, вес страницы 11 505 КиБ (из них собственные ресурсы 10 336,9 КиБ). А вот дальше — то, что обычно переворачивает разговор:

  • TTFB — 0 мс. Сервер отвечает мгновенно, HTTP/2 с alt-svc h3 на месте;
  • Total Blocking Time — 40 мс при пороге зелёной зоны ≤ 200 мс, то есть JavaScript не «вешает» страницу;
  • Cumulative Layout Shift — 0 при пороге ≤ 0,1: скачков вёрстки нет;
  • DOM — 594 элемента при глубине 16, минификация CSS и JS включена, дублей модулей нет;
  • категория «Поисковая оптимизация» — 100 баллов из 100.

Вывод, который экономит заказчику переписывание проекта: всё «тяжёлое и медленное» происходит после того, как сервер отдал ответ. Причина не в хостинге и не в дизайне, а в том, что первая отрисовка физически не может случиться раньше, чем скачается и выполнится весь клиентский код и дождётся ответов API.

Цепочка критических запросов главной: HTML 3,46 КиБ, CSS 95,7 КиБ, Google Fonts 220 КиБ, JS одним бандлом 774 КиБ, /api/articles 687 КиБ, восемь PNG галереи на 8 700 КиБ

Что именно замеряют: аудит скорости по слоям

«Сайт тормозит» — это симптом. Аудит разлагает его в список проверок, где у каждой есть инструмент, метрика и порог. Без порогов аудит превращается в список претензий, по которым невозможно принять работу.

СлойЧто ловимЧем измеряемПорог приёмки
Сервер и транспортОтсутствие сжатия, кэш, лишние заголовки, HTTP/2/3curl -sI -H "Accept-Encoding: br, gzip"content-encoding: br на HTML/CSS/JS/JSON; max-age=31536000, immutable на хэшированных ассетах
Критический путьКто кого ждёт до первой отрисовки, блокирующие запросыLighthouse «Цепочка критических запросов», DevTools PerformanceFCP ≤ 1,8 с, блокирующих отрисовку сторонних запросов — 0
Главный объект (LCP)Что именно является LCP и когда он отрисованLighthouse, разметка элемента LCPLCP ≤ 2,5 с; текст первого экрана присутствует в HTML сервера
МедиаФормат, вес, превышение исходника над контейнеромАудит изображений + замеры по файламWebP/AVIF, адаптивные ширины, вес галереи ≤ 400 КиБ
JavaScriptМёртвый код, отсутствие код-сплиттинга, длительные задачиLighthouse, visualizer по сборкеНеиспользуемый JS ≤ 100 КиБ, стартовый чанк ≤ 170 КиБ после сжатия, длительных задач > 50 мс — 0
ШрифтыЧисло начертаний, дублирующие запросы, блокировка отрисовкиNetwork-вкладка, аудит «Запросы, блокирующие отрисовку»≤ 3 файла woff2 ≤ 80 КиБ со своего домена, запросов к fonts.googleapis.com — 0
Доступность и мобильностьИмена кнопок, контраст, области нажатия, масштабированиеАудиты button-name, color-contrast, target-size, meta-viewport0 нарушений, категория «Специальные возможности» ≥ 95
Агентный слойllms.txt, манифест для ИИ-агентов, структурированные данные, OGПроверка «Агентного просмотра», валидаторы schema.org4/4 проверки, JSON-LD на ключевых маршрутах, ogImage заполнен

Где живёт вес страницы: разбираем 11 505 КиБ по полочкам

Вес — самая обманчивая метрика: две трети проблем видно не в сумме, а в разбивке. В этом аудите распределение получилось таким (значения — из отчёта и прямых замеров, доли — наш расчёт по этим же числам):

ЧтоЗначениеНорма / цельКомментарий
Восемь файлов галереи9 086 359 Б (8 873 КиБ)≤ 400 КиБ на все восемь≈ 77 % веса страницы; каждый файл от 921 010 до 1 565 980 Б, формат PNG
Исходник одного фото2703 × 1600 pxконтейнер 392 × 220 pxкартинка в 7 раз больше места, которое ей выделила вёрстка
Оценка экономии на изображениях1 708 КиБ—оценка Lighthouse: 447 КиБ за формат, 1 127,9 КиБ за размер
Стартовый JavaScript774,35 КиБ≤ 170 КиБ после сжатиявесь сайт одним файлом, внутри бандла — ни одной ссылки на другие чанки
Неиспользуемый JS503 КиБ≤ 100 КиБиз них собственный код — 460,3 КиБ из 739,8 КиБ, то есть 62 %
Ответ API статей687,19 КиБ≤ 10 КиБ39 объектов по 14 полям; только поле content даёт 369 КиБ — 54 % ответа
Шрифты220 КиБ, 7 файлов woff2≤ 80 КиБ, ≤ 3 файла8 начертаний трёх семейств + второй дублирующий запрос из JS
Блокировка отрисовки2 580 мс0 мс сторонних блокирующихсамая дорогая строка раздела «Статистика»
Запросов в критической цепочке15≤ 6два из них возвращают пустой массив и тратят по 977 мс

Отдельно — про честность в цифрах. В отчёте от 30 сентября фигурирует бандл 774,35 КиБ, а прямой замер 1 октября показал другой файл того же назначения весом 793 164 Б: между замером и аудитом сайт пересобрали. Это не «погрешность», а два разных бандла, и в ТЗ они названы раздельно, иначе оценка эффекта строится на файле, которого на сервере уже нет. Так же и с долями: «77 % веса» — это наш расчёт по замеренным байтам, а не строка из отчёта Lighthouse, и в документе это помечено так же.

Порядок починки: почему код переписывают последним

Пункты аудита зависимы: сжатие и вес усиливают эффект всех остальных правок, поэтому идут первыми, а архитектура рендеринга — самая трудоёмкая часть — замыкает первые два этапа. В этом аудите 26 пунктов: 6 блокирующих (P0), 13 важных (P1), 7 улучшений (P2), и распределены они по пяти этапам.

Пять этапов починки: серверная инфраструктура, данные и медиа, архитектура первого экрана, доступность, агентный слой

  1. Этап 1 — серверная инфраструктура. Включить brotli с gzip-fallback и прекомпрессией статики, поднять cache-control на хэшированных ассетах, убрать x-powered-by, сделать честные 404 вместо SPA-обёртки на любой путь. Не требует правок в клиентском коде и даёт измеримый эффект первым же деплоем: по нашей оценке — минус ~1,2 МБ передаваемых данных.
  2. Этап 2 — данные и медиа. Перестать отдавать полные тексты всех 39 статей ради пяти карточек на главной (выборка полей + limit), пересобрать восемь PNG в AVIF с WebP-fallback и отдать адаптивные ширины под реальные контейнеры. Самый большой выигрыш по объёму: минус ~8,5 МБ веса страницы.
  3. Этап 3 — архитектура первого экрана. Пререндер или SSR первого экрана, inline-данные вместо пяти запросов к API до отрисовки, маршрутный код-сплиттинг, self-hosting подсетов шрифтов. Именно этот этап переводит FCP и LCP в зелёную зону (цель — FCP ≤ 2,0 с, LCP ≤ 2,5 с), и именно он дороже всех.
  4. Этап 4 — доступность. 17 кнопок без доступного имени, около 20 элементов с недостаточным контрастом, более 30 областей нажатия меньше 24 × 24 px, maximum-scale=1, запрещающий масштабование. Правки изолированные, но требуют аккуратности: расширение кликабельных областей легко ломает раскладку точек-индикаторов.
  5. Этап 5 — прочее и агентный слой. Отложенная загрузка метрики (100 КиБ передаваемых данных и 162 мс основного потока), структурированные данные на главной, карты исходного кода, preload LCP-ресурсов.

Важное ограничение такого плана: бренд-палитра и типографика не меняются, миграция на другой фреймворк и переезд хостинга — вне объёма, а генерация изображений средствами ИИ вместо фотографий галереи недопустима — только перекодирование реальных снимков.

Что ловят прямые замеры, но не показывает Lighthouse

Отчёт — это 60 % аудита. Остальное находится, когда по тем же URL проходятся руками с curl и читают фактические заголовки и ответы. В этом проекте так нашлось семь вещей, которых в отчёте не было ни в одной секции:

  • Сжатия нет вообще. Не «слабое»: размеры ответов с Accept-Encoding: gzip, deflate, br, zstd и без него совпадают байт в байт — HTML 3 246 Б, JS 793 164 Б, CSS 97 703 Б, API-выдача 703 457 Б. Lighthouse подсвечивает это одной строкой «Без сжатия» с оценкой экономии 2 КиБ, потому что смотрит только на HTML. Проверяется это, кстати, без доступа к коду — заголовком Content-Encoding.
  • Кэш выключен там, где он обязан работать. Файлы с хэшем в имени отдаются с cache-control: public, max-age=0 — то есть при каждой загрузке скачиваются заново, хотя могли бы жить год.
  • Мягкие 404. Несуществующая страница отвечает HTTP 200 и SPA-обёрткой. Для робота и для ИИ-краулера это не «нет страницы», а «есть пустая страница» — такие URL индексируются и размывают качество массива.
  • Запрос за JSON получает HTML. /ai-catalog.json отдаёт 200, content-type: text/html, 3 246 Б — тот же шаблон. Манифеста для агентов нет, но ошибка не 404, а «битый JSON», что хуже: её не видно по коду ответа.
  • Устаревший чанк после деплоя отдаёт HTML вместо JS. Пользователь со старой закэшированной страницей молча получает неработающий сайт, а мониторинг видит 200 OK.
  • llms.txt ведёт в никуда. Файл на месте (1 949 Б), заголовок и markdown-ссылки есть — но все девять ссылок ведут на домен с опечаткой, который сайту не принадлежит. Формально «файл соответствует рекомендациям», фактически не работает ни одна ссылка.
  • Пустые запросы в критической цепочке. Два вызова API на главной возвращают пустой массив, но стоят по 977 мс каждый и блокируют отрисовку секций, которых нет.

Плюс к этому — ogImage пуст у всех 39 статей: в мессенджерах и в нейроответах ссылки на материалы уходят без превью, при том что og:image — самая дешёвая в правке часть SEO.

При чём тут GEO: «Агентный просмотр» как отдельная метрика

В Lighthouse появилась категория «Агентный просмотр» (beta) — проверки, видит ли сайт ИИ-агент: llms.txt, манифест ресурсов, доступность дерева, формы. В нашем замере пройдена 1 проверка из 4. Это уже не «на будущее»: страницы без серверного HTML агент читает как пустые, а пустая страница не цитируется.

Практический смысл для владельца сайта: ускорение и GEO чинятся одними и теми же пунктами. Пререндер первого экрана (P0) даёт и LCP, и индексируемый текст; честные 404 (P1) и живой llms.txt (P1) — и краулеру поисковика, и LLM-краулеру; заполненные ogImage (P2) — и клику из соцсетей, и превью в нейроответе. Поэтому аудит скорости в 2026 году логично делать вместе с GEO-аудитом сайта, а не как отдельную техническую услугу — особенно с учётом того, что нейроответы забирают часть органического трафика, и компенсировать это можно только цитируемостью страниц. Тот же принцип работает и на уровне отдельной посадочной: карточка товара против нейроответа.

Как принимать работу, чтобы не обмануть себя

Половина проваленных «ускорений» — это замеры, снятые в разных условиях. В ТЗ приёмка описана как часть задачи, а не как добрая воля исполнителя:

  • три прогона Lighthouse подряд и медиана, а не один удачный: лабораторные значения приблизительные, и сам отчёт помечает это;
  • отдельный прогон на десктопе, чтобы мобильная оптимизация не ухудшила десктоп;
  • визуальная сверка всех 48 URL из sitemap.xml на 392 и 1440 px со скриншотами «до» и «после» — отдельно контроль, что CLS не вырос с нуля;
  • функциональные сценарии, а не только метрики: галерея и свайп, карусель, квиз из трёх шагов с валидацией и отправкой, клики по телефону и соцсетям, навигация «блог → статья»;
  • проверка заголовков тем же curl, которым их находили: content-encoding, cache-control, код ответа на несуществующий путь;
  • аналитика после переноса счётчика: цели, ecommerce-слой и записи сессий должны остаться живыми;
  • полевые данные через 28 дней: блок с реальными Core Web Vitals появляется в поиске с задержкой, и «зелёно» в лаборатории не значит «зелёно» у пользователей.

И главное правило приёмаки: результат работ — это замер в тех же условиях, что и исходный. В этом проекте «замера после» нет, и мы не записываем его задним числом: это аудит и ТЗ, а не отчёт о внедрении, и все эффекты в нём помечены как ожидаемые.

Частые вопросы

Сколько стоит ускорить сайт?

Правильный ответ до аудита — «неизвестно», и вот почему. Разброс работ в одном и том же симптоме «долго грузится» в нашем случае: включить сжатие на уровне прокси (один деплой, ноль правок в клиенте) и перестроить доставку HTML с клиентского рендеринга на пререндер (этап 3, самый трудоёмкий). Это разница в порядках, а не в процентах. Поэтому сначала замер и приоритизация: часть пунктов закрывается за день, часть требует изменения сборки и регресс-прогона всех маршрутов.

Можно ли ускорить сайт, не переписывая его?

Да, и в этом аудите первые два этапа — сжатие, кэш, честные коды ответов, выборка полей в API, перекодирование восьми файлов галереи — не затрагивают архитектуру фронтенда вообще. Они же дают основную часть выигрыша по весу. Переписывание проекта на другой фреймворк — отдельное решение с отдельной оценкой, и в ТЗ оно прямо вынесено за объём работ.

Что важнее: балл Lighthouse или реальные секунды?

Ни одно из двух само по себе: балл — агрегированная оценка, секунды — лабораторные, и все три типа значений расходятся. Управляют порогами Core Web Vitals (LCP ≤ 2,5 с, INP и CLS в зелёной зоне) и проверяют их в поле, а не в одном прогоне. Балл полезен как шкала для сравнения «до/после» в одинаковых условиях.

Почему медленный сайт — это ещё и проблема доверия, а не только трафика?

Потому что пользователь не видит «TTFB 0 мс, виноват бандл». Он видит пустой экран 8 секунд и делает вывод о компании, а не о фронтенде. Для сайта с заявками на проект под ключ это напрямую сокращает число дошедших до формы, а пустой ogImage и мягкие 404 дополнительно снижают число тех, кто пришёл из соцсетей и нейроответов.

Что забрать из статьи: порядок действий

  1. Снять замер в фиксированных условиях (мобильная эмуляция, один и тот же движок) и сохранить отчёт — это baseline, без него спор о скорости превращается в обмен мнениями.
  2. Проверить заголовки напрямую: content-encoding, cache-control на хэшированных ассетах, код ответа на заведомо несуществующий путь.
  3. Разложить вес страницы по файлам и найти то, что больше 10 % от суммы: в нашем случае восемь PNG дали ≈ 77 %.
  4. Посмотреть, что реально нужно первой отрисовке, и перестать отдавать остальное: полные тексты 39 статей ради пяти карточек — это 687 КиБ вместо ~10 КиБ.
  5. Приоритизировать: сервер и вес → данные и медиа → рендеринг → доступность → прочее, с критерием приёмки на каждый пункт.
  6. Закрыть агентный слой: llms.txt с рабочими ссылками, структурированные данные, заполненные ogImage.
  7. Принимать по замеру в тех же условиях и по полевым данным через 28 дней, а не по одному удачному прогону.

Мы разбираем скорость по этим семи слоям и выдаём ТЗ, где у каждого пункта есть данные, критерий приёмки и ожидаемый эффект. Если нужен разбор вашего сайта — оставьте заявку в разделе контактов: снимем baseline и покажем, что чинится за один деплой, а что требует изменения сборки. Про то, как устроена работа над сайтом целиком, — услуга AI SEO и AI-консалтинг; пример такого аудита с цифрами — в кейсе «Технический аудит скорости коммерческого сайта: LCP 12,5 с и 26 пунктов ТЗ».