---
title: "LCP Optimization Guide: Jak poprawić Largest Contentful Paint"
description: "Kompletny przewodnik po optymalizacji LCP. Poznaj przyczyny wolnego ładowania, techniki optymalizacji obrazów, preload i najlepsze praktyki Core Web Vitals."
date: 2025-12-12
updated: 2026-03-16
category: Optymalizacja
tags: ["Core Web Vitals", "LCP", "Performance", "SEO", "Optymalizacja", "Lighthouse"]
url: https://uper.pl/blog/lcp-optimization-guide/
---

# LCP Optimization Guide: Jak poprawić Largest Contentful Paint

**Largest Contentful Paint (LCP)** to jedna z trzech kluczowych metryk [Core Web Vitals](/blog/core-web-vitals/), która mierzy czas ładowania największego widocznego elementu na stronie. Google wykorzystuje LCP jako czynnik rankingowy, a słaby wynik może negatywnie wpłynąć na pozycje w wynikach wyszukiwania.

## Czym jest LCP?

**LCP** mierzy czas od rozpoczęcia ładowania strony do momentu wyrenderowania największego elementu w widocznym obszarze (viewport). Typowo tym elementem jest:

- Główny obraz (hero image)
- Duży blok tekstu
- Element `<video>` z posterem
- Element z obrazem tła (background-image)

### Progi LCP

Google definiuje następujące progi:

| Wynik | Ocena |
|-------|-------|
| ≤ 2.5s | **Dobry** (zielony) |
| 2.5s - 4.0s | **Wymaga poprawy** (pomarańczowy) |
| > 4.0s | **Słaby** (czerwony) |

## Jak zmierzyć LCP?

### Narzędzia laboratoryjne (Lab data)

1. **Lighthouse** (DevTools → Lighthouse)
2. **PageSpeed Insights** - [pagespeed.web.dev](https://pagespeed.web.dev/)
3. **WebPageTest** - [webpagetest.org](https://www.webpagetest.org/)
4. **Chrome DevTools** → Performance panel

### Uper SEO Auditor

Wtyczka [Uper SEO Auditor](https://chromewebstore.google.com/detail/uper-seo-auditor/khhpbeckpphaoiemjdijhbfpjnendage) pokazuje wyniki Core Web Vitals bezpośrednio na analizowanej stronie, w tym LCP wraz ze wskazaniem konkretnego elementu odpowiedzialnego za wynik. Na przykładzie vwtirestore.com widać LCP 5.23s spowodowany przez duży obraz hero bez odpowiedniej optymalizacji:

![LCP 5.23s wykryty przez Uper SEO Auditor na vwtirestore.com — element LCP to obraz hero renderowany w 5232ms](/blog/vwtirestore-com-lcp-issues.png)

### Dane rzeczywiste (Field data)

1. **[Google Search Console](/blog/google-search-console/)** → Core Web Vitals
2. **Chrome UX Report (CrUX)** - rzeczywiste dane od użytkowników Chrome
3. **web-vitals library** - pomiary na własnej stronie

```javascript

onLCP(console.log);
// { name: 'LCP', value: 2547, rating: 'needs-improvement' }
```

### Identyfikacja elementu LCP

W Chrome DevTools:

1. Otwórz zakładkę **Performance**
2. Naciśnij **Ctrl+Shift+E** (nagrywanie z przeładowaniem)
3. Poszukaj znacznika **LCP** na timeline
4. Kliknij, aby zobaczyć który element jest LCP

## Główne przyczyny wolnego LCP

### 1. Wolny czas odpowiedzi serwera (TTFB)

**Time to First Byte** to czas od wysłania żądania do otrzymania pierwszego bajtu odpowiedzi. Jeśli TTFB jest wysoki, LCP automatycznie będzie opóźniony.

**Rozwiązania:**
- Użyj CDN (Cloudflare, Fastly, AWS CloudFront)
- Włącz kompresję Brotli/Gzip
- Zoptymalizuj zapytania do bazy danych
- Użyj cache'owania na serwerze (Redis, Memcached)
- Rozważ SSG zamiast SSR dla statycznych stron

### 2. Blokujące zasoby (render-blocking resources)

CSS i JavaScript w `<head>` blokują renderowanie strony.

**Rozwiązania:**

```html
<!-- Zamiast -->
<link rel="stylesheet" href="styles.css">

<!-- Użyj inline critical CSS -->
<style>
  /* Critical CSS dla above-the-fold */
  .hero { ... }
</style>
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
```

```html
<!-- JavaScript - użyj defer lub async -->
<script defer src="app.js"></script>
<script async src="analytics.js"></script>
```

### 3. Wolne ładowanie zasobów

Obrazy, fonty i inne zasoby muszą zostać pobrane zanim LCP zostanie wyrenderowany.

### 4. Client-side rendering

SPA (Single Page Applications) renderują treść po załadowaniu JavaScript, co opóźnia LCP.

**Rozwiązania:**
- Użyj SSR (Server-Side Rendering)
- Pre-rendering / SSG (Static Site Generation)
- Progressive Hydration

## Optymalizacja obrazów - klucz do dobrego LCP

Obrazy to najczęstszy element LCP. Ich optymalizacja ma największy wpływ na wynik.

### Format obrazów

| Format | Użycie | Kompresja |
|--------|--------|-----------|
| **WebP** | Uniwersalny, świetna kompresja | 25-35% mniejszy niż JPEG |
| **AVIF** | Najlepsza kompresja, ale wolniejsze dekodowanie | 50% mniejszy niż JPEG |
| **JPEG** | Fallback dla starszych przeglądarek | Baseline |
| **PNG** | Grafiki z przezroczystością | Bezstratny |

```html
<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Hero image" width="1200" height="600">
</picture>
```

### Responsywne obrazy

Nie ładuj obrazu 4K na telefonie!

```html
<img
  src="hero-800.jpg"
  srcset="
    hero-400.jpg 400w,
    hero-800.jpg 800w,
    hero-1200.jpg 1200w,
    hero-1600.jpg 1600w
  "
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
  alt="Hero image"
  width="1200"
  height="600"
>
```

### Lazy loading vs eager loading

Element LCP **NIE powinien** mieć `loading="lazy"`!

```html
<!-- Hero image (LCP) - ładuj natychmiast -->
<img src="hero.jpg" alt="Hero" fetchpriority="high">

<!-- Obrazy poniżej fold - lazy load -->
<img src="product.jpg" alt="Product" loading="lazy">
```

### Wymiary obrazów

Zawsze określaj `width` i `height` aby uniknąć layout shift:

```html
<img src="hero.jpg" width="1200" height="600" alt="Hero">
```

## Preload - przyspieszenie krytycznych zasobów

**Preload** informuje przeglądarkę, że zasób będzie potrzebny wkrótce i powinien być pobrany z wysokim priorytetem.

### Preload dla obrazu LCP

```html
<head>
  <link rel="preload" as="image" href="hero.webp" type="image/webp">
  <!-- Lub responsywnie -->
  <link
    rel="preload"
    as="image"
    href="hero-mobile.webp"
    media="(max-width: 600px)"
  >
  <link
    rel="preload"
    as="image"
    href="hero-desktop.webp"
    media="(min-width: 601px)"
  >
</head>
```

### Preload dla fontów

Fonty często opóźniają renderowanie tekstu:

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

### Preconnect do zewnętrznych domen

Jeśli LCP image jest na CDN, nawiąż połączenie wcześniej:

```html
<link rel="preconnect" href="https://cdn.example.com">
<link rel="dns-prefetch" href="https://cdn.example.com">
```

## Fetch Priority API

Nowoczesne przeglądarki wspierają **fetchpriority** do kontroli priorytetu zasobów:

```html
<!-- Wysoki priorytet dla LCP image -->
<img src="hero.jpg" fetchpriority="high" alt="Hero">

<!-- Niski priorytet dla mniej ważnych obrazów -->
<img src="decoration.jpg" fetchpriority="low" alt="Decoration">
```

```html
<!-- Wysoki priorytet dla krytycznego CSS -->
<link rel="stylesheet" href="critical.css" fetchpriority="high">
```

## Optymalizacja CSS

### Critical CSS inline

Wyodrębnij CSS potrzebny do renderowania above-the-fold i wstaw inline:

```html
<head>
  <style>
    /* Critical CSS - tylko dla viewport */
    header { ... }
    .hero { ... }
    nav { ... }
  </style>
  <!-- Reszta CSS asynchronicznie -->
  <link rel="preload" href="main.css" as="style" onload="this.rel='stylesheet'">
</head>
```

Narzędzia do ekstrakcji Critical CSS:
- **Critical** (npm package)
- **Critters** (webpack plugin)
- **PurgeCSS** (usuwanie nieużywanego CSS)

### Unikaj @import

```css
/* Źle - tworzy łańcuch żądań */
@import url('fonts.css');
@import url('components.css');

/* Dobrze - używaj <link> w HTML */
```

### Minifikacja i kompresja

```bash
# Minifikacja CSS
npx csso styles.css -o styles.min.css

# Kompresja Brotli
brotli -f styles.min.css
```

## Optymalizacja JavaScript

### Usunięcie render-blocking JS

```html
<!-- Źle - blokuje renderowanie -->
<script src="app.js"></script>

<!-- Dobrze - defer dla głównego JS -->
<script defer src="app.js"></script>

<!-- Async dla niezależnych skryptów -->
<script async src="analytics.js"></script>
```

### Code splitting

Nie ładuj całego bundla na każdej stronie:

```javascript
// React - lazy loading komponentów
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));

// Dynamiczny import
if (userClickedButton) {
  const module = await import('./feature.js');
}
```

### Tree shaking

Upewnij się, że bundler usuwa nieużywany kod:

```javascript
// Importuj tylko to, co potrzebujesz
import { debounce } from 'lodash-es'; // Dobrze
import _ from 'lodash'; // Źle - importuje całą bibliotekę
```

## Optymalizacja fontów

### Font-display

```css
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap; /* Pokaż fallback font, zamień gdy załadowany */
}
```

| Wartość | Zachowanie |
|---------|------------|
| `swap` | Natychmiastowy fallback, zamiana po załadowaniu |
| `optional` | Krótki fallback, może nie załadować fontu |
| `fallback` | Krótki fallback (100ms), potem zamiana |
| `block` | Niewidoczny tekst do załadowania (FOIT) |

### Subsetting fontów

Ładuj tylko potrzebne znaki:

```css
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153; /* Tylko Latin */
}
```

Narzędzia:
- **Glyphhanger** - automatyczne subsetting
- **Google Fonts** - parametr `&text=` lub `&subset=`

### Self-hosting fontów

Hostowanie fontów na własnym serwerze eliminuje zewnętrzne żądania:

```html
<!-- Zamiast Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter" rel="stylesheet">

<!-- Hostuj lokalnie -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
```

## Optymalizacja serwera i CDN

### Włącz HTTP/2 lub HTTP/3

HTTP/2 pozwala na równoległe ładowanie zasobów:

```nginx
# nginx.conf
server {
    listen 443 ssl http2;
    # ...
}
```

### Cache headers

```nginx
# Długi cache dla statycznych zasobów
location ~* \.(js|css|png|jpg|webp|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}
```

### Kompresja Brotli

```nginx
# nginx.conf
brotli on;
brotli_comp_level 6;
brotli_types text/html text/css application/javascript image/svg+xml;
```

### Edge caching (CDN)

Użyj CDN z edge lokalizacjami blisko użytkowników:
- Cloudflare
- Fastly
- AWS CloudFront
- Vercel Edge Network

## Checklist optymalizacji LCP

### Priorytet 1 - Najważniejsze

- [ ] Zidentyfikuj element LCP na stronie
- [ ] Preload dla obrazu/zasobu LCP
- [ ] `fetchpriority="high"` dla elementu LCP
- [ ] Usuń `loading="lazy"` z elementu LCP
- [ ] Optymalizuj obrazy (WebP/AVIF, kompresja)

### Priorytet 2 - Ważne

- [ ] Critical CSS inline
- [ ] Defer/async dla JavaScript
- [ ] Preconnect do zewnętrznych domen
- [ ] Responsywne obrazy (srcset)
- [ ] font-display: swap dla fontów

### Priorytet 3 - Dodatkowe

- [ ] HTTP/2 lub HTTP/3
- [ ] Kompresja Brotli
- [ ] CDN dla statycznych zasobów
- [ ] Self-hosting fontów
- [ ] Code splitting JavaScript

## Podsumowanie

**LCP** to krytyczna metryka wydajności, która bezpośrednio wpływa na doświadczenie użytkownika i pozycje w Google. Aby sprawdzić, jak Twoja strona wypada pod kątem wydajności i UX, przeprowadź [darmowy audyt SXO](/audyt-sxo/). Kluczowe działania to:

1. **Zidentyfikuj element LCP** - najczęściej hero image
2. **Preload krytycznych zasobów** - obraz LCP, fonty
3. **Optymalizuj obrazy** - format, rozmiar, responsywność
4. **Eliminuj blokujące zasoby** - Critical CSS, defer JS
5. **Popraw TTFB** - CDN, cache, optymalizacja serwera

Regularne monitorowanie LCP w Google Search Console i Lighthouse pomoże utrzymać dobre wyniki i reagować na problemy. Cel to **poniżej 2.5 sekundy** dla 75% użytkowników.

LCP to tylko jeden z elementów układanki - sprawdź [kompletny przewodnik po technologiach web i ich wpływie na ranking Google](/blog/technologie-web-seo-ranking-google/), aby poznać pełny obraz optymalizacji technicznej.

<FaqBlog
  questions={[
    {
      question: 'Co to jest LCP i jaki wynik jest dobry?',
      answer: 'LCP (Largest Contentful Paint) mierzy czas renderowania największego widocznego elementu na stronie — zwykle hero image lub nagłówka. Dobry wynik to <strong>poniżej 2,5 sekundy</strong>. Wynik powyżej 4 sekund Google klasyfikuje jako słaby.'
    },
    {
      question: 'Jakie są najczęstsze przyczyny wolnego LCP?',
      answer: 'Trzy główne przyczyny to: wolny czas odpowiedzi serwera (TTFB powyżej 800ms), niezoptymalizowane obrazy hero (brak WebP/AVIF, brak kompresji) oraz render-blocking CSS i JavaScript, które opóźniają renderowanie strony.'
    },
    {
      question: 'Jak zoptymalizować obrazy, aby poprawić LCP?',
      answer: 'Użyj nowoczesnych formatów (<strong>WebP lub AVIF</strong>), ustaw atrybut <strong>fetchpriority="high"</strong> na obrazie hero, dodaj <strong>preload</strong> w nagłówku HTML i upewnij się, że obrazy mają określone wymiary width/height.'
    },
    {
      question: 'Czy CDN pomaga poprawić LCP?',
      answer: 'Tak, CDN (Content Delivery Network) znacząco poprawia LCP, zmniejszając odległość między serwerem a użytkownikiem. Skraca to zarówno TTFB, jak i czas pobierania zasobów. W testach CDN może poprawić LCP nawet o 40-60% dla użytkowników oddalonych od serwera.'
    }
  ]}
  heading="Często zadawane pytania"
  id="faq"
/>

## Źródła

1. **web.dev - Largest Contentful Paint (LCP)**
[https://web.dev/articles/lcp](https://web.dev/articles/lcp)

2. **web.dev - Optimize LCP**
[https://web.dev/articles/optimize-lcp](https://web.dev/articles/optimize-lcp)

3. **Google Search Central - Core Web Vitals**
[https://developers.google.com/search/docs/appearance/core-web-vitals](https://developers.google.com/search/docs/appearance/core-web-vitals)

4. **Chrome Developers - Fetch Priority API**
[https://developer.chrome.com/docs/lighthouse/performance/priority-hints](https://developer.chrome.com/docs/lighthouse/performance/priority-hints)

5. **web.dev - Preload critical assets**
[https://web.dev/articles/preload-critical-assets](https://web.dev/articles/preload-critical-assets)

6. **MDN - Resource Hints**
[https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload)
