PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Оптимизация LCP: как я довёл Web Vitals до 1.5 секунд на реальном проекте

    Оптимизация LCP: как я довёл Web Vitals до 1.5 секунд на реальном проекте

    Аватар автора Оптимизация LCP: как я довёл Web Vitals до 1.5 секунд на реальном проекте

    Антон Ларичев

    Иконка календаря27 марта 2026
    performancehtmlmiddleИконка уровня middle
    Картинка поста Оптимизация LCP: как я довёл Web Vitals до 1.5 секунд на реальном проекте

    Введение

    Оптимизация LCP — одна из ключевых задач при работе с производительностью веб-приложений. Largest Contentful Paint (LCP) показывает, как быстро пользователь видит основной контент страницы, и напрямую влияет на поведенческие факторы и позиции в поиске Google. В этой статье я расскажу, как на реальном проекте довёл показатель LCP с 4.8 до 1.5 секунд, и покажу конкретные приёмы, которые вы можете применить уже сегодня.

    Core Web Vitals — это набор метрик Google для оценки пользовательского опыта. LCP считается «хорошим», если загрузка основного контента происходит за 2.5 секунды или быстрее. Всё, что выше — красная зона, которая бьёт и по SEO, и по конверсии.

    Диагностика: как найти узкие места LCP

    Прежде чем оптимизировать, нужно понять, что именно тормозит. Для этого я использовал три инструмента:

    • Lighthouse в Chrome DevTools — для лабораторных замеров
    • PageSpeed Insights — для полевых данных (CrUX)
    • Web Vitals Extension — для мониторинга в реальном времени

    На моём проекте LCP-элементом оказалось hero-изображение размером 1920x1080 в формате PNG (2.3 МБ). Lighthouse показал LCP = 4.8 секунды на мобильных. Разбивка задержки выглядела так:

    TTFB (Time to First Byte):   1.2 сек
    Загрузка ресурса (изображение): 2.8 сек
    Рендеринг:                     0.8 сек
    

    Стало понятно: основная проблема — размер изображения и отсутствие предзагрузки.

    Оптимизация изображений для LCP

    Первый и самый эффективный шаг — работа с изображениями. Вот что я сделал:

    Переход на современные форматы (WebP и AVIF)

    Конвертация hero-изображения из PNG в WebP сократила размер с 2.3 МБ до 320 КБ — почти в 7 раз. AVIF дал ещё лучший результат: 210 КБ.

    <picture>
      <source srcset="/hero.avif" type="image/avif">
      <source srcset="/hero.webp" type="image/webp">
      <img src="/hero.png" alt="Hero изображение" width="1920" height="1080">
    </picture>
    

    Адаптивные изображения через srcset

    Нет смысла загружать картинку 1920px на мобильном экране шириной 375px. Атрибут srcset решает эту проблему:

    <img
      srcset="
        /hero-480.webp 480w,
        /hero-768.webp 768w,
        /hero-1200.webp 1200w,
        /hero-1920.webp 1920w
      "
      sizes="100vw"
      src="/hero-1920.webp"
      alt="Hero изображение"
      width="1920"
      height="1080"
      fetchpriority="high"
    />
    

    Обратите внимание на fetchpriority="high" — этот атрибут говорит браузеру загружать LCP-изображение с максимальным приоритетом.

    Preload для LCP-элемента

    Браузер не может начать загрузку изображения, пока не распарсит HTML и CSS. Preload позволяет начать загрузку раньше:

    <link
      rel="preload"
      as="image"
      href="/hero-1200.webp"
      type="image/webp"
      fetchpriority="high"
      imagesrcset="/hero-480.webp 480w, /hero-768.webp 768w, /hero-1200.webp 1200w"
      imagesizes="100vw"
    />
    

    Один только preload сократил LCP на 0.6 секунды.

    Как ускорить загрузку основного контента: шрифты и CSS

    Оптимизация шрифтов

    Кастомные шрифты часто блокируют рендеринг. Два ключевых приёма:

    @font-face {
      font-family: 'CustomFont';
      src: url('/fonts/custom.woff2') format('woff2');
      font-display: swap; /* Показываем текст сразу, шрифт подгрузится позже */
      unicode-range: U+0400-04FF, U+0020-007F; /* Только кириллица и латиница */
    }
    

    Preload для основного шрифта:

    <link rel="preload" href="/fonts/custom.woff2" as="font" type="font/woff2" crossorigin>
    

    Подгрузка только нужного unicode-range вместо полного набора символов сократила размер шрифта с 180 КБ до 45 КБ.

    Удаление блокирующего CSS

    Критический CSS — стили, необходимые для отрисовки первого экрана — я вынес в инлайн:

    <head>
      <!-- Критический CSS инлайн -->
      <style>
        .hero { position: relative; min-height: 60vh; }
        .hero img { width: 100%; height: auto; display: block; }
        /* ... остальные стили первого экрана */
      </style>
      <!-- Некритический CSS загружается асинхронно -->
      <link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'">
    </head>
    

    Серверная оптимизация: снижаем TTFB

    TTFB в 1.2 секунды — это слишком. Вот что помогло:

    Кеширование и CDN

    Подключение CDN (Cloudflare) снизило TTFB с 1.2 до 0.3 секунды для большинства пользователей. Настройка заголовков кеширования:

    # nginx.conf
    location ~* \.(webp|avif|woff2|js|css)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    location / {
        add_header Cache-Control "public, max-age=3600, stale-while-revalidate=86400";
    }
    

    Сжатие Brotli

    Brotli сжимает эффективнее gzip на 15-25%:

    brotli on;
    brotli_types text/html text/css application/javascript application/json image/svg+xml;
    brotli_comp_level 6;
    

    Устранение блокирующих скриптов

    Сторонние скрипты — аналитика, чаты, виджеты — часто блокируют рендеринг. Перенёс их загрузку:

    <!-- Было: блокирующий скрипт -->
    <script src="/analytics.js"></script>
    
    <!-- Стало: отложенная загрузка -->
    <script src="/analytics.js" defer></script>
    
    <!-- Или загрузка после полной отрисовки страницы -->
    <script>
      window.addEventListener('load', () => {
        const script = document.createElement('script');
        script.src = '/analytics.js';
        document.body.appendChild(script);
      });
    </script>
    

    Итоговые результаты оптимизации

    Каждый шаг давал измеримый вклад в улучшение LCP:

    Оптимизация Снижение LCP
    WebP/AVIF + srcset -1.8 сек
    Preload LCP-изображения -0.6 сек
    CDN + кеширование -0.5 сек
    Инлайн критического CSS -0.2 сек
    Оптимизация шрифтов -0.1 сек
    Defer сторонних скриптов -0.1 сек
    Итого 4.8 -> 1.5 сек

    Частые ошибки при оптимизации LCP

    • Lazy load на LCP-элементе. Атрибут loading="lazy" на hero-изображении увеличивает LCP — браузер откладывает загрузку самого важного элемента. Lazy load нужен только для контента ниже первого экрана.
    • Отсутствие width и height у изображений. Без указания размеров браузер не может зарезервировать место, что приводит к сдвигу макета (CLS) и пересчёту рендеринга.
    • Загрузка всех шрифтов на каждой странице. Если на странице используется только один шрифт — не подключайте пять начертаний «на всякий случай».
    • Игнорирование мобильных данных. Lighthouse в DevTools показывает лабораторные данные. Реальные пользователи на 3G будут видеть совсем другую картину — проверяйте полевые данные в PageSpeed Insights.

    Заключение

    Оптимизация LCP — это не магия, а последовательная работа с изображениями, шрифтами, CSS, серверными настройками и сторонними скриптами. Самый большой выигрыш дают современные форматы изображений и preload. Каждый из описанных шагов можно внедрить за день, а результат будет виден сразу в Lighthouse и PageSpeed Insights. Начните с диагностики, определите свой LCP-элемент — и применяйте оптимизации по очереди, замеряя эффект каждого шага.

    Иконка глаза997

    Комментарии

    0

    Постройте личный план изучения Neovim - практика и настройка до уровня Middle — бесплатно!

    Neovim - практика и настройка — часть карты развития Frontend, Backend, DevOps

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    React и Redux Toolkit

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Zustand

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Next.js - с нуля

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.7
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста Регулярные выражения в JavaScript: полное руководство
    Иконка аватараАнтон
    Иконка календаря06 августа 2026
    JavaScriptрегулярные выраженияregexp+ 2middleИконка уровня middle

    Регулярные выражения в JavaScript: полное руководство

    Регулярные выражения в JavaScript позволяют искать, проверять и заменять текст по шаблону. Разбираем синтаксис, методы и частые ошибки с примерами.

    Иконка чипа0
    Иконка глаза140
    Иконка комментариев0
    Картинка поста React useState и useEffect: полное руководство 2024
    Иконка аватараАнтон
    Иконка календаря29 июля 2026
    ReactuseStateuseEffect+ 3juniorИконка уровня junior

    React useState и useEffect: полное руководство 2024

    Разбираем useState и useEffect с нуля: как управлять состоянием и побочными эффектами в React-компонентах с реальными примерами.

    Иконка чипа0
    Иконка глаза714
    Иконка комментариев0
    Картинка поста Docker для разработчиков: с чего начать и как применять
    Иконка аватараАнтон
    Иконка календаря21 июля 2026
    dockerdevopsконтейнеры+ 3juniorИконка уровня junior

    Docker для разработчиков: с чего начать и как применять

    Docker — инструмент контейнеризации, который решает проблему «у меня работает». Установка, первый контейнер, Dockerfile и docker-compose с нуля.

    Иконка чипа0
    Иконка глаза922
    Иконка комментариев0
    Иконка чипа0