Как я довёл этот сайт до идеального результата Lighthouse
Короткий и конкретный чек-лист, который довёл этот сайт от неплохого результата Lighthouse до идеальных 100 баллов по Performance, Accessibility, Best Practices и SEO.

Чтобы отчёт Lighthouse показал четыре зелёных 100 балла на реальной странице, а не на урезанной демке, потребовался не расплывчатый «давайте всё оптимизируем», а короткий и конкретный список правок. Вот что именно сработало на этом сайте.
Начните с базовой структуры
Прежде чем заниматься производительностью, нужно навести порядок в базовых вещах на странице: настоящий title и meta description для каждой страницы, canonical URL, теги Open Graph и Twitter Card, а также граф JSON-LD с Person/WebSite. Ничего экзотического, но всё это должно быть динамическим для каждой страницы, а не скопированным из одного шаблона. Если сайт поддерживает несколько языков, добавьте ещё и альтернативы hreflang вместе с тегом x-default, сгенерированные из одного источника истины, а не продублированные вручную на каждой странице.
Устраните главную ошибку с изображениями
Самым большим приростом производительности здесь стала замена четырёх сырых скриншотов с iPhone (PNG 1284×2778px, от 456КБ до 1.3МБ каждый) на компонент <Image> из Astro: вывод в WebP, явные width/height, чтобы браузер заранее резервировал место под изображение, и размер, который реально соответствует тому, как изображение отображается на странице. Эти четыре картинки в сумме упали с 3.5МБ до менее 200КБ.
<Image src={Hook} width={600} format="webp" quality={80} alt="..." />
Исправьте враньё в атрибуте sizes
Атрибут sizes="100vw" корректен только если изображение действительно занимает всю ширину вьюпорта. На этом сайте оно находится внутри контейнера с отступами, поэтому реальная ширина — это 100vw минус эти отступы. Ошибка здесь не просто снижает баллы в лабораторном тесте, она заставляет браузер каждый раз при реальном визите загружать изображение большего размера, чем нужно:
sizes="(min-width: 1024px) 34vw, calc(100vw - 2.5rem)"
Перестаньте отправлять блокирующую отрисовку таблицу стилей
Небольшой, 7.8КБ, внешний CSS-файл добавлял целый сетевой round trip в критический путь отрисовки, прежде чем страница вообще могла что-то отрисовать. Astro может встроить его прямо в HTML вместо того, чтобы подключать отдельной ссылкой:
// astro.config.mjs
export default defineConfig({
build: { inlineStylesheets: 'always' },
});
Одна строка — и блокирующий запрос полностью исчезает из сетевого waterfall.
Откладывайте всё стороннее
Аналитика — классический случай: ей не нужно запускаться до того, как посетитель вообще увидел страницу. Заглушка dataLayer/gtag загружается сразу, чтобы не терять события, но сам скрипт gtag.js подгружается только при первом взаимодействии (клик, нажатие клавиши, скролл, тач) либо через несколько секунд после полной загрузки страницы, смотря что наступит раньше. Это не даёт стороннему скрипту конкурировать с первой отрисовкой самой страницы.
Добавьте дополнительные структурированные данные
BreadcrumbList на внутренних страницах и страницах блога, а также массив sameAs в узле Person, указывающий на реальные профили LinkedIn и GitHub, — это дешёвые добавления с реальным, пусть и скромным, эффектом: больше шансов попасть в rich results и более сильный сигнал того, что это конкретный узнаваемый человек, а не анонимная страница.
Будьте готовы к сюрпризам платформы
Самая неожиданная находка вообще была не в коде. У Cloudflare Pages есть переключатель «Managed robots.txt» (в разделе AI Crawl Control), который незаметно добавляет правила Disallow для GPTBot, ClaudeBot, Google-Extended и ещё нескольких AI-краулеров поверх того robots.txt, который сайт реально отдаёт. Это не затрагивает обычную поисковую индексацию — Googlebot и Bingbot не страдают, — но означает, что AI-поисковики вообще не увидят контент, пока этот переключатель не отключат вручную. Стоит проверить независимо от того, на какой платформе всё развёрнуто: файл, который видит браузер, не всегда совпадает с файлом в репозитории.
Результат

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