Metricum Lab

Вебпродуктивність · LCP · Root-cause діагностика

Як виправити Largest Contentful Paint (LCP): діагностика TTFB, Load Delay, Load Time і Render Delay

Я не починаю LCP-діагностику зі стиснення всіх зображень або спроби отримати зелений Lighthouse score. Спочатку визначаю реальний LCP-елемент і field signal, а потім дивлюся, де саме витрачається час: server response, discovery, transfer чи rendering. Fix має бити в цей subpart, а field data після релізу — підтвердити результат.

Yurii Pekach Technical SEO & Web Performance ConsultantОпублікованоОновлено35 хв читання
Діагностичний таймлайн Largest Contentful Paint із TTFB, resource load delay, resource load duration та element render delay і пріоритизованим hero-елементом.

Коротка відповідь

Щоб виправити LCP, спочатку розкладіть його на складові. Підтвердьте реальний LCP-кандидат, а потім окремо виміряйте TTFB, resource load delay, resource load duration та element render delay. Велике зображення справді може бути причиною — у проєктах я зустрічав LCP-images понад 4–5 MB, — але field data показує, що багато повільних origin-ів втрачають ще більше часу до початку завантаження зображення. Зробіть змістовний hero дешевим для рендерингу, критичні ресурси — ранньо discoverable і правильно пріоритизованими, а результат підтверджуйте в RUM/CrUX.

≤2.5 s

Good LCP

Поточний good threshold — LCP не більше 2.5 секунди на 75-му перцентилі окремо для mobile і desktop.

1.29 s vs 350 ms

Field median для poor LCP

У Google-аналізі image-LCP для poor origin-ів медіанний p75 resource load delay становив близько 1.29 s, а image load duration — близько 350 ms.

≤0.8 s

Орієнтир TTFB

web.dev наводить 0.8 секунди або менше як приблизний орієнтир TTFB для більшості сайтів; TTFB не є Core Web Vital.

Діагностична модель

Шукайте, де саме витрачається 2.5-секундний LCP budget

Одна метрика складається з кількох різних затримок, і кожна потребує іншого fix.

LCP показує момент рендерингу найбільшого eligible image, text block або video у viewport. Good threshold — ≤2.5 s на p75. Для дебагінгу я перестаю дивитися на LCP як на одну непрозору цифру і розкладаю її на TTFB → resource load delay → resource load duration → element render delay. Тоді питання ‘як прискорити сторінку?’ перетворюється на конкретне: який subpart забирає час?

Кастомна схема

Чотири LCP subparts як карта root cause

Timeline від navigation до LCP paint: відповідь сервера, очікування до старту critical request, transfer ресурсу та затримка перед рендерингом елемента.

Чотири LCP subparts як карта root causeTimeline від navigation до LCP paint: відповідь сервера, очікування до старту critical request, transfer ресурсу та затримка перед рендерингом елемента.TTFBnavigation → first byteLoad delayfirst byte → requestLoad durationrequest → response endRender delayresource ready → paintLCP = TTFB + resource load delay + resource load duration + element render delay
Починайте з найбільшого measured bucket, а не автоматично з image compression.

Спочатку candidate

Підтвердьте фактичний LCP-елемент до будь-якої оптимізації

LCP selector не задається напряму, але архітектура hero суттєво впливає на те, який eligible елемент стане найбільшим у viewport.

Фраза ‘LCP-елемент можна обрати’ звучить дивно, але в ній є практичний сенс. Browser сам обирає candidate серед eligible видимого контенту і може змінювати його, коли рендериться більший елемент. Натомість ми визначаємо hero composition, visual hierarchy, розміри, rendering order і те, чи домінуватиме text block, image, video poster або background image. У моїй практиці я переробляв hero так, щоб основний зміст був швидким текстовим блоком, а важке декоративне зображення не домінувало у viewport. Це нормальна інформаційна архітектура; ховати корисний контент тільки заради score — ні.

Знайдіть candidate і доведіть, чому саме він став LCP

  1. 1

    Зафіксуйте route і viewport

    Профілюйте device/viewport, який наближений до affected field cohort. Видимий розмір candidate залежить від viewport.

    КритерійУ нотатках є route, viewport і test conditions.

  2. 2

    Запишіть LCP trace

    Запишіть page load у Chrome DevTools Performance та відкрийте LCP marker або insight.

    ШляхChrome DevTools → Performance → Record → Insights → LCP by phase / LCP badge

    КритерійDetails показує LCP candidate і timing breakdown.

  3. 3

    Порівняйте з реальною visual hierarchy

    Чи є LCP candidate справді головним hero content, чи декоративний media asset без потреби став найбільшим елементом?

    КритерійВи можете пояснити, чому candidate є largest meaningful content, або маєте обґрунтовану причину змінити hero architecture.

  4. 4

    Після redesign перевірте candidate знову

    LCP candidate може змінюватися під час завантаження. Після змін layout/media запишіть новий trace.

    КритерійФінальний LCP candidate підтверджено, а не припущено.

Кастомна схема

Зробіть primary hero content дешевим для LCP

Порівняння hero, де важке декоративне media домінує у viewport, та text-led hero, де змістовний primary content рендериться рано, а supporting media не займає зайву площу.

Зробіть primary hero content дешевим для LCPПорівняння hero, де важке декоративне media домінує у viewport, та text-led hero, де змістовний primary content рендериться рано, а supporting media не займає зайву площу.4–5 MB decorative hero?largest visible candidateredesignMeaningful text herofast, stable primary contentsupporting mediaDo not hide important content to game LCP. Make the real visual hierarchy efficient.
Browser обирає LCP. Layout визначає, який eligible контент достатньо великий і видимий, щоб конкурувати.

Evidence before fixes

Чотири subparts підказують, який fix має сенс першим

Однаковий 4-second LCP може бути наслідком зовсім різних bottlenecks.

Field analysis Google добре показує, чому не варто зводити LCP до image compression. Для origin-ів із poor image LCP медіанний p75 breakdown був приблизно 2,270 ms TTFB + 1,290 ms image load delay + 350 ms image load duration + 360 ms render delay. Більшість poor-LCP origin-ів витрачали менше 10% p75 LCP безпосередньо на download LCP image. Це population-level evidence, а не діагноз вашої сторінки, але воно показує: правильний image fix може не торкнутися головного bottleneck.

Використовуйте dominant subpart як генератор root-cause гіпотези
Dominant subpartЙмовірний напрямЩо дивитися першимТиповий first move
TTFBRedirects, cache miss, повільний origin/backendNavigation timing, CDN/cache, Server-TimingСкоротити redirects; поліпшити caching/CDN/origin
Resource load delayLCP asset пізно discoverable або слабкий priorityNetwork initiator chain, request start, PriorityВідкрити asset для parser/preload і пріоритизувати
Resource load durationЗайві bytes, неправильні dimensions/formatTransferred bytes, srcset candidate, cache/CDNПравильний candidate, format і transfer size
Element render delayRender-blocking CSS/fonts, main-thread, CSR/hydrationPerformance trace після responseEndПрибрати observed blocker або раніше рендерити hero HTML

Resource load duration

Якщо LCP image величезний — зменште bytes, але після цього виміряйте інші subparts

Надмірно великі assets залишаються простою і частою регресією на сайтах без системного media pipeline.

Найбільш банальний LCP failure, який я бачу на практиці, — oversized image. На невеликих ecommerce/content сайтах, де uploads накопичуються без performance budget, я зустрічав LCP images понад 4–5 MB. Це моє project observation, а не рекомендований threshold. Діагностика проста: порівняйте rendered dimensions, selected source candidate і transferred bytes. Якщо 700 px hero тягне multi-megabyte original на 3000 px, це очевидний transfer waste.

Зменшуйте transfer cost без втрати якості й стабільності layout

  1. 1

    Перевірте фактичний selected candidate

    У DevTools Network подивіться transferred size і ресурс, який `srcset`/`sizes` обрав для потрібного viewport/DPR.

    ШляхChrome DevTools → Network → Img → LCP request

    КритерійЗафіксовано rendered size, selected source і transferred bytes.

  2. 2

    Створіть right-sized variants

    Віддавайте responsive candidates замість одного master asset для всіх viewport. Modern formats використовуйте тоді, коли вони реально зменшують bytes без неприйнятної втрати якості.

    КритерійTarget viewport більше не завантажує full-size master без потреби.

  3. 3

    Зарезервуйте geometry

    Збережіть `width`/`height` або еквівалентний aspect ratio, щоб LCP fix не створив CLS.

    КритерійImage має reserved dimensions і зміна не додає layout shifts.

  4. 4

    Переміряйте subparts

    Переконайтеся, що resource load duration справді зменшився, і перевірте, чи bottleneck не перемістився в load delay або render delay.

    КритерійBefore/after trace показує очікуване скорочення потрібної фази.

STATICALLY VERIFIED · Responsive LCP image with explicit geometry and priority

<picture>
  <source
    type="image/avif"
    srcset="/hero-640.avif 640w, /hero-1280.avif 1280w"
    sizes="(max-width: 720px) 100vw, 1200px">
  <img
    src="/hero-1280.webp"
    srcset="/hero-640.webp 640w, /hero-1280.webp 1280w"
    sizes="(max-width: 720px) 100vw, 1200px"
    width="1200"
    height="675"
    fetchpriority="high"
    alt="Describe the meaningful hero content">
</picture>

Markup syntax checked on 2026-09-08. Replace file paths, breakpoints, dimensions and alt text with values from the actual layout. Do not add high priority to multiple competing images.

Resource load delay

Зробіть LCP resource ранньо discoverable і дайте high priority лише справді критичному asset

200 KB image, який почав завантажуватися на 1.3 s пізніше, може втратити більше LCP часу, ніж більший файл із раннім discovery.

Resource load delay — це час після TTFB до старту request LCP resource. Типові причини: image додається JavaScript-ом, `src` схований у custom lazy loader, або LCP є CSS background, про який browser дізнається тільки після завантаження і парсингу CSS. У field analysis також видно relationship між dependency chain та LCP: median LCP зростав приблизно від 2.15 s при 0 dependent requests до 2.54 s при 1 і 2.85 s при 2. Дайте browser URL критичного resource якомога ближче до initial HTML.

Кастомна схема

Direct discovery швидший за пізній request chain

Fast path: parser бачить LCP image у HTML. Slow path: HTML чекає CSS/JavaScript, і тільки потім browser отримує image URL.

Direct discovery швидший за пізній request chainFast path: parser бачить LCP image у HTML. Slow path: HTML чекає CSS/JavaScript, і тільки потім browser отримує image URL.Early discoveryHTML parsersees <img>LCP request startshigh relative priorityPaintshort delayLate discovery chainHTMLCSS / JSdiscover URLafter dependencyLCP fetch
Preload вирішує discovery; fetchpriority задає relative priority. Це різні інструменти.

STATICALLY VERIFIED · Preload only when the LCP asset is otherwise discovered late

<!-- Best case: the LCP image is directly discoverable in HTML. -->
<img src="/hero.webp" width="1200" height="675" fetchpriority="high" alt="...">

<!-- If the LCP is a CSS background or otherwise not parser-discoverable: -->
<link
  rel="preload"
  as="image"
  href="/hero-background.webp"
  fetchpriority="high">

Markup syntax checked on 2026-09-08. Do not blindly preload an image already discovered early, and make sure preload URL/type/candidate matches the resource the page actually uses to avoid duplicate or wasted fetches.

Network contention

Не дозволяйте near-fold images конкурувати з реальним LCP

Offscreen не завжди означає ‘request не почнеться’: browser heuristics можуть дозволити сусіднім images забирати bandwidth.

На image-heavy сторінках я окремо перевіряю конкуренцію від media трохи нижче першого viewport. У дизайні вони можуть виглядати ‘поза екраном’, але кілька сусідніх images іноді починають fetching рано й займають bandwidth, поки hero ще не завантажився. Browser lazy-loading використовує розраховану distance from viewport, а не жорстку лінію fold. Chrome Fetch Priority guidance окремо наводить carousel, де offscreen images можуть виявитися ‘достатньо близькими’; для неважливих сусідів lower priority може бути доречним.

Пріоритизуйте images за цінністю в initial viewport
РольLoadingPriority hintЩо перевірити
Фактичний LCP heroEager / parser discoveryHigh, якщо справді criticalРанній start; немає інших high images
2–3 carousel slideЗалежить від UXLow може бути доречнимНе затримує first visible slide/LCP
Явно below-fold mediaLazyAuto або LowНемає initial contention; встигає до scroll
CSS background LCPPreloadHigh на preload за потребиОдин matching request, без duplicate fetch

Server + render path

Виправте TTFB і render delay до того, як звинувачувати image pipeline

Якщо HTML приходить пізно або page не може paint після готовності LCP resource, image compression має обмежений ефект.

TTFB стоїть перед усіма наступними LCP phases. web.dev дає ≤0.8 s як rough guide для більшості сайтів, наголошуючи, що TTFB не є Core Web Vital. У наведеному field dataset poor-LCP origins мали median p75 TTFB близько 2.27 s — майже весь good-LCP budget. З іншого боку, element render delay виникає, коли LCP resource вже готовий, але CSS, fonts, main-thread work, client rendering або hydration не дають елементу з’явитися.

Відокремте server delay від render delay

  1. 1

    Спочатку navigation timing

    Зафіксуйте TTFB, redirects, CDN/cache та origin response. Повільний HTML зсуває всі наступні фази.

    КритерійЄ baseline і зрозуміло, чи TTFB materially обмежує target 2.5 s.

  2. 2

    Перевірте, чи resource вже готовий

    Порівняйте завершення resource і LCP paint. Великий gap після responseEnd — render delay, а не download delay.

    ШляхChrome DevTools → Performance → LCP by phase → Element render delay

    КритерійTrace показує, чи element очікує після готовності resource.

  3. 3

    Знайдіть blocking work

    Перевірте render-blocking styles, web fonts, long tasks, CSR/hydration всередині цього interval.

    КритерійObserved blocker реально перетинає render-delay window; causality не виведена лише з file size.

  4. 4

    Раніше віддавайте meaningful hero

    Для client-rendered routes розгляньте SSR/static hero HTML, якщо це прибирає реальну rendering dependency. Не вважайте SSR автоматично швидшим — переміряйте trade-off.

    КритерійТой самий meaningful content paint відбувається раніше без CWV/UX regression.

Field attribution

Збирайте достатньо RUM attribution, щоб бачити LCP phase у реальних користувачів

CrUX підтверджує field problem; first-party attribution може зв’язати poor LCP із target, resource і конкретною фазою.

`web-vitals` attribution build повертає LCP target, image URL (коли є) та ті самі чотири timing components, які використовує цей гайд. Це набагато корисніше, ніж просто `LCP=4.1s`. Payload має бути privacy-safe і normalized: групуйте template/release/candidate type, а не DOM text чи user identifiers. Для загальної field-vs-lab методики використовуйте гайд з Core Web Vitals testing.

STATICALLY VERIFIED · Capture LCP target and four timing subparts with web-vitals attribution

import {onLCP} from 'web-vitals/attribution';

onLCP(({value, rating, id, attribution}) => {
  const payload = {
    value,
    rating,
    id,
    path: location.pathname,
    target: attribution.target ?? null,
    resource: attribution.url ?? null,
    timeToFirstByte: attribution.timeToFirstByte,
    resourceLoadDelay: attribution.resourceLoadDelay,
    resourceLoadDuration: attribution.resourceLoadDuration,
    elementRenderDelay: attribution.elementRenderDelay
  };

  navigator.sendBeacon(
    '/rum/lcp',
    new Blob([JSON.stringify(payload)], {type: 'application/json'})
  );
});

Syntax checked on 2026-09-08. Requires web-vitals v5 attribution build and a site-specific endpoint. Normalize routes and review consent, sampling, retention and sensitive-data policy before production collection.

Корисні LCP RUM dimensions без зайвого збору контенту
FieldЯке рішення підтримуєPrivacy/quality
Normalized route/templateЯкий page family регресує?Приберіть IDs і sensitive query params
LCP target/candidate typeText, image чи інший candidate pattern?Stable generated selector; без DOM text
4 LCP subpartsЯка phase домінує в real users?Агрегуйте лише за достатнього sample
Release/build IDЯкий deploy змінив distribution?Technical build ID, не user ID

Метод Metricum Lab

Мій LCP workflow: field signal → candidate → phase → один fix → field validation

Робота завершена лише тоді, коли causal chain прозорий, а production distribution рухається в потрібний бік.

Я працюю консервативно: спочатку підтверджую LCP як проблему real users, далі визначаю candidate і dominant subpart, відтворюю mechanism, змінюю один causal lever і порівнюю trace. Faster lab run — deployment gate, але не фінальний доказ. RUM може швидко показати зміну для вашого cohort, а CrUX реагує повільніше як aggregated field dataset. Після hero/image fix я також перевіряю CLS; якщо причина в rendering architecture — використовую JavaScript SEO debugging workflow.

Виконайте відтворюваний LCP fix cycle

  1. 1

    Field baseline

    Зафіксуйте p75 LCP для affected mobile/desktop population і measurement window; додайте first-party RUM, якщо є.

    КритерійIssue прив’язаний до real field cohort, а не до single lab score.

  2. 2

    Підтвердьте candidate

    Зафіксуйте final LCP element/resource у target viewport/journey.

    КритерійНазвано фактичний candidate, а не assumed hero asset.

  3. 3

    Назвіть dominant subpart

    Класифікуйте root-cause hypothesis як TTFB, load delay, load duration або render delay.

    КритерійHypothesis прив’язана до measured milliseconds конкретної phase.

  4. 4

    Змініть один causal lever

    Наприклад: right-size image, early discovery, priority, server response або observed render blocker.

    КритерійPatch напряму пов’язаний із dominant phase без unrelated changes.

  5. 5

    Повторіть однакові lab conditions

    Порівнюйте equivalent traces, щоб не переплутати fix із run-to-run variation.

    КритерійПотрібний subpart стабільно поліпшується без значної regression elsewhere.

  6. 6

    Після release поверніться у field

    Спочатку RUM по route/release, потім CrUX/Search Console як повільніше external confirmation.

    КритерійProduction cohort змінюється в очікуваний бік із достатнім sample і без прихованої device/template regression.

Першоджерела та документація

Джерела

Кожне змінне твердження про пошукову систему, браузер, інтерфейс або технічну поведінку в матеріалі прив’язане до актуального першоджерела.

  1. web.dev / Chrome team Largest Contentful Paint (LCP) (відкриється в новій вкладці)Current LCP definition, p75 threshold, eligible elements, candidate behavior and field/lab measurement guidance.
  2. web.dev / Chrome team Optimize Largest Contentful Paint (відкриється в новій вкладці)Canonical four-subpart LCP model and guidance on TTFB, resource discovery, priority, load duration and render delay.
  3. web.dev / Chrome team Common misconceptions about how to optimize LCP (відкриється в новій вкладці)Field-data analysis of LCP subparts across CrUX origins, including p75 medians and request-chain relationship.
  4. Chrome for Developers Performance insights: Get actionable insights on your website's performance (відкриється в новій вкладці)Current DevTools path for LCP details and the Timings breakdown into TTFB, load delay, load time and render delay.
  5. Chrome for Developers Insights sidebar in the DevTools Performance panel (відкриється в новій вкладці)Current LCP by phase workflow and optional field p75 subpart overlay in Performance Insights.
  6. web.dev / Chrome team Optimize resource loading with the Fetch Priority API (відкриється в новій вкладці)Resource-priority behavior, LCP-image prioritization, carousel/near-fold competition and preload versus fetchpriority guidance.
  7. MDN Web Docs fetchpriority HTML attribute (відкриється в новій вкладці)Current standardized high/low/auto priority hint semantics and warning to use the hint sparingly.
  8. MDN Web Docs <img>: The Image Embed element (відкриється в новій вкладці)Current image loading, fetchpriority, width/height and lazy-loading semantics.
  9. MDN Web Docs Responsive images (відкриється в новій вкладці)Responsive image selection with srcset and sizes for serving appropriately sized assets.
  10. web.dev / Chrome team Time to First Byte (TTFB) (відкриється в новій вкладці)TTFB definition, lab/field measurement and the current rough guide of 0.8 seconds or less for most sites.
  11. GoogleChrome / GitHub web-vitals library README (відкриється в новій вкладці)Current v5 attribution build and LCP attribution fields including target, URL and four LCP subparts.

Потрібна допомога з діагностикою та впровадженням?

Перетворіть LCP зі score на implementation-ready root-cause backlog

Metricum Lab може зв’язати field LCP regressions із server timing, resource discovery, image delivery, render-path traces і post-release validation та пріоритизувати fixes, які реально скорочують user-visible delay.

Оптимізація Core Web Vitals