Programování

Core Web Vitals: jak zrychlit web a zlepšit LCP, INP a CLS

Co měří LCP, INP a CLS, jaké jsou hraniční hodnoty, jak je změřit na reálných uživatelích a konkrétní opravy, které mají největší efekt.

12. 10. 2026 · 4 min čtení

Core Web Vitals jsou tři metriky, kterými Google měří uživatelský zážitek z načítání a používání stránky. Ovlivňují hodnocení ve vyhledávání (jako jeden z mnoha signálů), ale hlavně odpovídají tomu, co lidé skutečně cítí: jak rychle uvidí obsah, jak rychle stránka reaguje a jestli jim pod prstem neuskakuje.

Tři metriky a jejich hranice

Metrika Co měří Dobré Špatné
LCP – Largest Contentful Paint kdy se vykreslí největší prvek (hero obrázek, nadpis) ≤ 2,5 s > 4 s
INP – Interaction to Next Paint jak rychle stránka vizuálně zareaguje na kliknutí či klávesu ≤ 200 ms > 500 ms
CLS – Cumulative Layout Shift jak moc obsah neočekávaně poskakuje ≤ 0,1 > 0,25

Hodnotí se 75. percentil návštěv – aby web prošel, musí být metrika dobrá u alespoň tří čtvrtin uživatelů. INP v březnu 2024 nahradilo starší metriku FID.

Laboratorní vs. terénní data

  • Lab data (Lighthouse, PageSpeed Insights – horní část): simulace na jednom zařízení. Skvělé na ladění, ale INP v nich změřit nejde (nikdo neklikne), Lighthouse místo něj ukazuje Total Blocking Time.
  • Field data (Chrome UX Report v PageSpeed Insights, Search Console → Core Web Vitals): skutečná data uživatelů Chrome za posledních 28 dní. Rozhoduje to, co je tady.

Vlastní měření od reálných návštěvníků získáte knihovnou web-vitals:

import { onLCP, onINP, onCLS } from 'web-vitals';

function send(metric) {
  navigator.sendBeacon('/analytics', JSON.stringify({
    name: metric.name,
    value: metric.value,
    rating: metric.rating,       // 'good' | 'needs-improvement' | 'poor'
    page: location.pathname,
  }));
}

onLCP(send);
onINP(send);
onCLS(send);

sendBeacon odešle data i při zavírání stránky, kdy běžný fetch může být přerušen.

Zlepšení LCP

LCP prvek najdete v DevTools → Performance (nahrajte načtení stránky, v sekci Timings je značka LCP) nebo v reportu Lighthouse.

1. Hlavní obrázek načtěte co nejdřív.

<img src="hero.webp" alt="…" width="1200" height="600" fetchpriority="high">

Nikdy na něj nedávejte loading="lazy" – to je jedna z nejčastějších příčin špatného LCP. Pokud je obrázek v CSS jako background-image, prohlížeč ho objeví pozdě; pomůže preload:

<link rel="preload" as="image" href="hero.webp" fetchpriority="high">

2. Zmenšete obrázky. Formáty WebP a AVIF jsou výrazně menší než JPEG při podobné kvalitě. Používejte srcset, aby mobil nestahoval obrázek pro desktop.

3. Zrychlete odpověď serveru (TTFB). Cachování HTML, CDN, komprese (gzip/brotli), HTTP/2 nebo HTTP/3. Pokud server odpovídá 1,5 s, LCP pod 2,5 s jen těžko dáte.

4. Neblokujte vykreslení. Skripty v hlavičce označte defer, kritické CSS držte malé. Webové fonty načítejte s font-display: swap a hlavní font přednačtěte:

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

Zlepšení INP

INP zhoršují dlouhé úlohy na hlavním vlákně – cokoli nad 50 ms blokuje reakci na vstup.

1. Najděte viníka. DevTools → Performance → nahrajte záznam a klikněte na problematické tlačítko. Dlouhé úlohy jsou označené červeným rohem. Rozšíření Web Vitals nebo knihovna web-vitals/attribution ukáže, která interakce a který skript to byl.

2. Rozdělte práci a pusťte prohlížeč ke slovu.

button.addEventListener('click', async () => {
  showSpinner();                       // okamžitá vizuální odezva

  // uvolnit hlavní vlákno, aby se spinner vykreslil
  await new Promise(r => setTimeout(r, 0));

  for (const chunk of chunks(items, 100)) {
    process(chunk);
    await new Promise(r => setTimeout(r, 0));
  }
});

V Chromiu existuje i scheduler.yield(), který pokračuje s vyšší prioritou; v ostatních prohlížečích použijte setTimeout jako zálohu.

3. Omezte JavaScript. Méně kódu = méně parsování a spouštění. Rozdělte bundle (import() pro části, které nejsou potřeba hned), odstraňte nepoužívané knihovny a prověřte skripty třetích stran – chatovací widgety, analytiku a reklamy.

4. V Reactu zabraňte zbytečným rerenderům velkých stromů a dlouhé seznamy virtualizujte (např. TanStack Virtual). Pro méně naléhavé aktualizace je tu useTransition.

Zlepšení CLS

1. Rozměry u médií. Vždy width a height u <img>, <video> a <iframe>, nebo CSS aspect-ratio:

.video-embed { aspect-ratio: 16 / 9; width: 100%; }

2. Rezervujte místo pro dynamický obsah. Reklamy, cookie lišty, bannery a obsah načítaný přes API potřebují předem vymezený prostor (min-height). Cookie lištu dejte jako překryv (position: fixed), ne nad obsah.

3. Fonty. Výměna záložního fontu za webový může posunout text. Pomůže preload a deskriptory size-adjust, ascent-override v @font-face, které sladí rozměry záložního fontu.

4. Animace dělejte přes transform a opacity, ne přes top, height nebo margin – ty mění layout.

CLS prvky najdete v DevTools → Performance, v sekci Layout shifts.

Postup v praxi

  1. Otevřete PageSpeed Insights, podívejte se na field data a určete nejhorší metriku.
  2. Najděte konkrétní prvek nebo interakci (Lighthouse, Performance panel).
  3. Opravte jednu věc, nasaďte, změřte.
  4. Sledujte Search Console – terénní data se aktualizují s 28denním oknem, zlepšení se projeví postupně.

Optimalizujte primárně mobil se střední třídou výkonu – tam jsou problémy nejvýraznější a tam je většina návštěv.