Технический аудит скорости сайта: что чинить первым, если 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.
Что именно замеряют: аудит скорости по слоям
«Сайт тормозит» — это симптом. Аудит разлагает его в список проверок, где у каждой есть инструмент, метрика и порог. Без порогов аудит превращается в список претензий, по которым невозможно принять работу.
| Слой | Что ловим | Чем измеряем | Порог приёмки |
|---|---|---|---|
| Сервер и транспорт | Отсутствие сжатия, кэш, лишние заголовки, HTTP/2/3 | curl -sI -H "Accept-Encoding: br, gzip" | content-encoding: br на HTML/CSS/JS/JSON; max-age=31536000, immutable на хэшированных ассетах |
| Критический путь | Кто кого ждёт до первой отрисовки, блокирующие запросы | Lighthouse «Цепочка критических запросов», DevTools Performance | FCP ≤ 1,8 с, блокирующих отрисовку сторонних запросов — 0 |
| Главный объект (LCP) | Что именно является LCP и когда он отрисован | Lighthouse, разметка элемента LCP | LCP ≤ 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-viewport | 0 нарушений, категория «Специальные возможности» ≥ 95 |
| Агентный слой | llms.txt, манифест для ИИ-агентов, структурированные данные, OG | Проверка «Агентного просмотра», валидаторы schema.org | 4/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 КиБ за размер |
| Стартовый JavaScript | 774,35 КиБ | ≤ 170 КиБ после сжатия | весь сайт одним файлом, внутри бандла — ни одной ссылки на другие чанки |
| Неиспользуемый JS | 503 КиБ | ≤ 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 — серверная инфраструктура. Включить brotli с gzip-fallback и прекомпрессией статики, поднять
cache-controlна хэшированных ассетах, убратьx-powered-by, сделать честные 404 вместо SPA-обёртки на любой путь. Не требует правок в клиентском коде и даёт измеримый эффект первым же деплоем: по нашей оценке — минус ~1,2 МБ передаваемых данных. - Этап 2 — данные и медиа. Перестать отдавать полные тексты всех 39 статей ради пяти карточек на главной (выборка полей +
limit), пересобрать восемь PNG в AVIF с WebP-fallback и отдать адаптивные ширины под реальные контейнеры. Самый большой выигрыш по объёму: минус ~8,5 МБ веса страницы. - Этап 3 — архитектура первого экрана. Пререндер или SSR первого экрана, inline-данные вместо пяти запросов к API до отрисовки, маршрутный код-сплиттинг, self-hosting подсетов шрифтов. Именно этот этап переводит FCP и LCP в зелёную зону (цель — FCP ≤ 2,0 с, LCP ≤ 2,5 с), и именно он дороже всех.
- Этап 4 — доступность. 17 кнопок без доступного имени, около 20 элементов с недостаточным контрастом, более 30 областей нажатия меньше 24 × 24 px,
maximum-scale=1, запрещающий масштабование. Правки изолированные, но требуют аккуратности: расширение кликабельных областей легко ломает раскладку точек-индикаторов. - Этап 5 — прочее и агентный слой. Отложенная загрузка метрики (100 КиБ передаваемых данных и 162 мс основного потока), структурированные данные на главной, карты исходного кода,
preloadLCP-ресурсов.
Важное ограничение такого плана: бренд-палитра и типографика не меняются, миграция на другой фреймворк и переезд хостинга — вне объёма, а генерация изображений средствами ИИ вместо фотографий галереи недопустима — только перекодирование реальных снимков.
Что ловят прямые замеры, но не показывает 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 дополнительно снижают число тех, кто пришёл из соцсетей и нейроответов.
Что забрать из статьи: порядок действий
- Снять замер в фиксированных условиях (мобильная эмуляция, один и тот же движок) и сохранить отчёт — это baseline, без него спор о скорости превращается в обмен мнениями.
- Проверить заголовки напрямую:
content-encoding,cache-controlна хэшированных ассетах, код ответа на заведомо несуществующий путь. - Разложить вес страницы по файлам и найти то, что больше 10 % от суммы: в нашем случае восемь PNG дали ≈ 77 %.
- Посмотреть, что реально нужно первой отрисовке, и перестать отдавать остальное: полные тексты 39 статей ради пяти карточек — это 687 КиБ вместо ~10 КиБ.
- Приоритизировать: сервер и вес → данные и медиа → рендеринг → доступность → прочее, с критерием приёмки на каждый пункт.
- Закрыть агентный слой:
llms.txtс рабочими ссылками, структурированные данные, заполненныеogImage. - Принимать по замеру в тех же условиях и по полевым данным через 28 дней, а не по одному удачному прогону.
Мы разбираем скорость по этим семи слоям и выдаём ТЗ, где у каждого пункта есть данные, критерий приёмки и ожидаемый эффект. Если нужен разбор вашего сайта — оставьте заявку в разделе контактов: снимем baseline и покажем, что чинится за один деплой, а что требует изменения сборки. Про то, как устроена работа над сайтом целиком, — услуга AI SEO и AI-консалтинг; пример такого аудита с цифрами — в кейсе «Технический аудит скорости коммерческого сайта: LCP 12,5 с и 26 пунктов ТЗ».