
Lighthouse 100%: что реально влияет на оценку и какие инструменты помогут
ДБ
Дмитрий Борисенко
Зелёная сотня в Lighthouse — цель, за которой гоняются, толком не понимая, из чего она складывается. В итоге неделю сжимают картинки, а балл не двигается, потому что тормозит не картинка, а скрипт аналитики.
Разберёмся, что именно считает Lighthouse, какие метрики весят больше всего и с чего начинать, чтобы усилия не уходили впустую.
Из чего складывается оценка
Lighthouse считает четыре независимые категории: Performance, Accessibility, Best Practices и SEO. Сотня в одной ничего не говорит о трёх остальных — их и чинят по-разному.

Хороший пример: производительность вылизана до сотни, а Best Practices — семьдесят три. Категории независимы, и оптимизация скриптов не починит недостающий фавикон или ошибку в консоли.
Обратите внимание на предупреждение под кругами: Lighthouse честно предупреждает, что данные в IndexedDB могли повлиять на замер, и советует прогонять аудит в режиме инкогнито. Это не мелочь — кэш, расширения и уже сохранённые данные легко дают разброс в десяток баллов между прогонами.
Сложнее всего даётся Performance, потому что это не одна цифра, а взвешенная сумма пяти метрик:
| Метрика | Вес | Что измеряет |
|---|---|---|
| Total Blocking Time (TBT) | 30% | Сколько главный поток заблокирован JavaScript |
| Largest Contentful Paint (LCP) | 25% | Когда отрисовался самый крупный элемент |
| Cumulative Layout Shift (CLS) | 25% | Насколько прыгает вёрстка при загрузке |
| First Contentful Paint (FCP) | 10% | Когда появился первый пиксель контента |
| Speed Index | 10% | Как быстро страница заполняется визуально |
Отсюда главный вывод, который экономит дни работы: TBT весит 30% — больше любой другой метрики. Улучшение TBT влияет на итоговый балл втрое сильнее, чем такое же улучшение FCP.
А TBT — это про JavaScript. Не про картинки, не про шрифты, не про CSS. Если у вас проседает Performance, первым делом смотрите на скрипты, а не на ассеты.
Performance: с чего начинать
1. Сначала JavaScript, потом всё остальное
TBT растёт, когда главный поток занят долгими задачами и не может ответить на действие пользователя. Виноваты обычно три вещи:
- сторонние скрипты — аналитика, чаты, пиксели рекламы. Часто это половина всего JS на странице;
- гидратация тяжёлых компонентов;
- работа в момент загрузки — парсинг больших JSON, инициализация библиотек.
Что делать по порядку:
<!-- Аналитика не нужна для первой отрисовки — выполнится после парсинга -->
<script src="/analytics.js" defer></script>
Важно не перепутать defer и async. Оба не блокируют парсинг загрузкой,
но async выполняет скрипт сразу, как только тот скачался, — прямо посреди
разбора страницы. Для TBT это худший вариант: главный поток встаёт в
непредсказуемый момент. defer откладывает выполнение до конца парсинга, и
скрипты идут по порядку. Для стороннего кода почти всегда нужен defer.
Ещё эффективнее — не грузить сторонние скрипты до первого действия пользователя. Чат, который подключается по клику на иконку, а не при загрузке страницы, стоит ноль миллисекунд TBT.
2. Минифицируйте CSS и JavaScript
Lighthouse прямо ругается аудитами Minify CSS и Minify JavaScript. Обычно это делает сборщик, но если стили подключаются отдельным файлом или вы правите что-то руками, сжать код стоит.
Минификация убирает комментарии, переносы и пробелы, сокращает #ffffff до
#fff, а 0px до 0. Файл худеет на 20–40%, и поверх этого лучше сжимается
gzip: в минифицированном коде меньше повторяющегося «воздуха».
Сжать CSS: минификация онлайн
Вставьте стили и получите сжатый CSS: комментарии и пробелы уйдут, размер файла упадёт на 20–40%.
Попробовать →
JavaScript Минификатор
Оптимизируйте и сжимайте JavaScript код для лучшей производительности
Попробовать →
3. Картинки: вес и размеры
Картинки редко влияют на TBT, зато напрямую бьют по LCP — а это ещё 25%. Крупное изображение в первом экране почти всегда и есть тот самый Largest Contentful Paint.
Три правила:
- не грузите больше, чем нужно. Если картинка отображается 400px шириной, а весит 2400px — вы платите за пиксели, которых никто не увидит;
- современные форматы. WebP или AVIF вместо JPEG экономят 25–50% веса;
- не откладывайте LCP-картинку.
loading="lazy"на главном изображении первого экрана — классическая ошибка: вы своими руками замедляете метрику, которую пытаетесь ускорить. Lazy-загрузка нужна тому, что ниже сгиба.
И самый действенный однострочник — fetchpriority="high". Браузер по
умолчанию не знает, какая из картинок главная, и обнаруживает LCP-изображение
поздно. Атрибут говорит ему: эту грузи первой.
<img
src="hero.avif"
width="1200"
height="630"
fetchpriority="high"
alt="Заголовок статьи"
/>
Часто это даёт больше, чем пересжатие картинки: вы не уменьшаете вес, а просто перестаёте заставлять браузер угадывать.
Проверить реальные размеры и вес изображения, прежде чем класть его в проект:
Проверка размера изображений
Мгновенно проверьте размеры, размер файла и формат изображений
Попробовать →
Мелкие иконки и декоративные SVG выгоднее встроить прямо в CSS — это минус один сетевой запрос на каждую:
SVG URL кодировщик
Кодируйте SVG для использования в CSS свойстве background-image
Попробовать →
4. CLS: зарезервируйте место заранее
CLS весит те же 25%, что и LCP, но чинится куда проще — и его почти всегда игнорируют.
Вёрстка прыгает, когда браузер узнаёт размеры элемента уже после того, как нарисовал страницу. Лечится это одним принципом: место под элемент должно быть известно заранее.
Главный фикс — самый скучный: проставьте картинке атрибуты width и
height. Именно этого требует аудит unsized-images. Браузер сам выведет из
них пропорцию и зарезервирует место, при этом картинка останется резиновой.
<!-- Браузер знает пропорцию до загрузки и не сдвинет вёрстку -->
<img src="hero.avif" width="1200" height="630" alt="" />
img {
width: 100%;
height: auto; /* сохраняет пропорцию из атрибутов */
}
aspect-ratio в CSS нужен там, где реальных размеров нет заранее, — например у
контейнера под эмбед. Но не вешайте фиксированное соотношение на все картинки
подряд: aspect-ratio: 16 / 9 раздавит любую, у которой пропорция другая. Если
всё же ставите — добавляйте object-fit: cover.
То же самое с рекламными блоками, эмбедами и всем, что подгружается: задайте контейнеру минимальную высоту, иначе появившийся баннер сдвинет весь контент под собой.
Отдельная причина CLS — шрифты. Когда системный шрифт сменяется на фирменный, текст меняет метрики и строки перескакивают.
И здесь широко распространён вредный совет: «поставьте font-display: swap».
Наоборот — swap и есть причина сдвига: он гарантирует, что подмена
произойдёт, а значит произойдёт и скачок вёрстки.
Лечится это тем, что запасной шрифт подгоняют по метрикам под фирменный — тогда подмена происходит без сдвига:
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}
Радикальный вариант — font-display: optional: браузер подменит шрифт, только
если тот успел загрузиться за ~100 мс, иначе просто останется на системном, и
сдвига не будет вовсе.
Предзагрузка шрифта тоже полезна, но она лечит не CLS, а задержку отрисовки текста:
<link
rel="preload"
href="/fonts/inter.woff2"
as="font"
type="font/woff2"
crossorigin
/>
Accessibility: контраст валит чаще всего
В категории доступности сотня достижима почти всегда — там нет метрик, есть конкретные проверки. И самая частая провальная проверка — контраст текста и фона.
Порог по WCAG: 4.5:1 для обычного текста и 3:1 для крупного (от 24px или от 18.66px жирного). Ловушка в том, что контраст — это не «разница цветов на глаз»: жёлтый кажется ярким и заметным, но белый текст на жёлтом фоне почти нечитаем, потому что яркости слишком близки.
Чаще всего проваливают:
- плейсхолдеры в полях ввода — светло-серый на белом даёт классические 2.5:1;
- неактивные элементы — задизейбленную кнопку делают почти невидимой;
- текст поверх фотографий — фон меняется от пикселя к пикселю;
- индикатор фокуса — ему нужны те же 3:1, иначе навигация с клавиатуры
превращается в угадайку. Рисуется он псевдоклассом
:focus-visible— разбор в статье про псевдоклассы и псевдоэлементы.
Проверить пару цветов и сразу увидеть вердикт по AA и AAA:
Контраст текста и фона: проверка по WCAG
Подберите цвет текста и фона так, чтобы надпись читалась: коэффициент контрастности и вердикт по WCAG считаются сразу.
Попробовать →
Остальное в этой категории — механика, которую стоит просто пройти по списку:
alt у картинок, lang у <html>, подписи (label) у полей форм, осмысленный
порядок заголовков без прыжков с h1 на h4.
Best Practices и SEO: быстрые сто процентов
Эти две категории — самые дешёвые. Обычно до сотни не хватает мелочей.
Best Practices проверяет отсутствие ошибок в консоли, HTTPS, корректные размеры изображений и то, что вы не используете устаревшие API. Чаще всего балл роняет именно консоль: одна ошибка от стороннего скрипта — и категория уже не сотня.
Отдельно стоит сказать, чего Lighthouse больше не проверяет. Аудиты фавиконок и манифеста жили в категории PWA, а её удалили в Lighthouse 12 — на оценку они не влияют вовсе. Иконки по-прежнему нужны (браузер, вкладка, экран «Домой» на телефоне), но ради балла их делать бессмысленно:
Генератор Favicon
Создайте favicon для вашего веб-сайта всех размеров
Попробовать →
SEO проверяет базу: <title>, <meta name="description">, доступность для
индексации, осмысленные тексты ссылок. Аудит читаемого размера шрифта, к слову,
тоже удалён в Lighthouse 12. Lighthouse не проверяет Open Graph, но соцсети —
проверяют, и ломается там чаще всего именно превью ссылки:
OpenGraph валидатор
Проверяйте OpenGraph теги для соцсетей
Попробовать →
Честно: 100% в Lighthouse — не то же самое, что быстрый сайт
И это главное, что стоит понимать, прежде чем гнаться за цифрой.
Lighthouse — лабораторный тест. Он запускается один раз, на эмуляции медленного устройства, в стерильных условиях. Реальные пользователи приходят с разных устройств, из разных сетей, с включёнными расширениями и кэшем.
Поэтому:
- TBT — не INP. Lighthouse меряет TBT в лаборатории, а Google в поиске учитывает INP — отзывчивость на реальные действия реальных людей. Можно иметь 100% и медленный отклик на клик;
- балл скачет. Один и тот же сайт даёт 92% и 100% в двух прогонах подряд — это нормально, метрики шумят;
- поле важнее лаборатории. Данные CrUX (Core Web Vitals из Chrome) — вот что влияет на ранжирование, а не число в отчёте.
Сотня — хороший ориентир и отличный способ найти конкретные проблемы: Lighthouse честно показывает, какой скрипт блокирует поток и какой текст не читается. Но цель — не цифра, а сайт, который быстро отвечает живому человеку с телефоном в метро.
Порядок действий, если коротко
- Откройте вкладку Performance и посмотрите, что даёт TBT. Скорее всего,
сторонние скрипты — выносите их на
defer(не наasync!) или на первое действие пользователя. - Найдите LCP-элемент (Lighthouse его подсвечивает). Уберите с него
lazy, отдайте в современном формате, не грузите лишние пиксели. - Зарезервируйте место под всё, что подгружается:
widthиheightна картинки,min-heightна эмбеды, метрики запасного шрифта вместоfont-display: swap. - Прогоните контраст по всем текстовым парам — это самая частая ошибка доступности.
- Закройте мелочи в Best Practices и SEO: иконки, мета-теги, консоль.
И только потом — сжимать CSS. Не наоборот.


