Obrazy bez kompromisów: pipeline dla stron wizytówkowych, który trzyma LCP < 1,8 s
Jak zaprojektować pipeline obrazów, który utrzyma Twoją stronę wizytówkową poniżej 1,8 s LCP na mobile? Oto kompletna instrukcja: od audytu po checklistę wdrożeniową.
Nowoczesna strona wizytówkowa dla lokalnej firmy musi ładować się błyskawicznie na wolniejszym LTE, bo inaczej traci 30-50% potencjalnych zapytań. Ten przewodnik pokazuje, jak zbudować pipeline dla obrazów, który realnie utrzyma Largest Contentful Paint (LCP) poniżej 1,8 s i jednocześnie zadba o wzorowe Core Web Vitals bez ciężkich wtyczek czy skomplikowanych CDN-ów.
Dla kogo i jaki efekt
- Strony wizytówkowe, landing pages typu „usługa + miasto” oraz mini-portfolio usług lokalnych.
 - Firmy, które korzystają z lekkich generatorów (Astro, Eleventy) i prostego CMS (np. Keystatic), ale chcą zachować kontrolę nad mediami.
 - Cel: LCP < 1,8 s na mobile, zerowy CLS, stabilny INP bez dodatkowego JavaScriptu.
 
Najczęstsze błędy, które zabijają LCP na wizytówkach
- Hero ważący 800 KB – 2 MB w JPEG/PNG bez kompresji ani formatu nowej generacji.
 - Brak 
srcsetisizes, przez co nawet na telefonie pobierana jest wersja desktopowa (1920 px). - Hero jako 
background-imagew CSS – brak możliwości preloadera, brak altów i priorytetyzacji. loading="lazy"na obrazie LCP – przeglądarka czeka, aż użytkownik przewinie.- Brak atrybutów 
width/height→ layout shift i gorszy CLS. - Karuzele i slidery JS; w 90% przypadków wystarczy jedno statyczne zdjęcie + CTA.
 - Brak budżetu wydajności: konwersja i naming plików według uznania, zero kontroli cache.
 
Szybki audyt: odpal PageSpeed Insights na mobilu, wejdź w zakładkę „Diagnostics” i sprawdź, co wskazano jako element LCP. Jeśli to hero, przechodzisz przez kolejne kroki z tego artykułu.
Jak przeglądarka wybiera obraz – podstawy, które musisz znać
srcset + sizes
srcsetdostarcza zestaw wariantów rozdzielczości (np. 480w, 768w, 1200w).sizesmówi, jak szeroki będzie obraz w danym breakpointcie, dzięki czemu przeglądarka wybierze najmniejszy wystarczający plik.
<img
  src="/images/hero-1440.avif"
  srcset="/images/hero-480.avif 480w, /images/hero-768.avif 768w, /images/hero-1440.avif 1440w"
  sizes="(max-width: 768px) 92vw, (max-width: 1280px) 70vw, 1200px"
  alt="Nowoczesna pracownia stolarska w Bytomiu"
  width="1200"
  height="800"
  fetchpriority="high"
  decoding="async"
  loading="eager"
>
<picture> dla AVIF/WebP
Używamy <picture>, aby dać przeglądarce preferowane formaty:
<picture>
  <source type="image/avif" srcset="/images/hero-768.avif 768w, /images/hero-1440.avif 1440w" sizes="100vw">
  <source type="image/webp" srcset="/images/hero-768.webp 768w, /images/hero-1440.webp 1440w" sizes="100vw">
  <img src="/images/hero-1440.jpg" alt="Zespół serwisu hydraulicznego przy pracy" width="1440" height="880" loading="eager">
</picture>
Safari na macOS/iOS nie wspiera jeszcze AVIF w 100%, dlatego fallback w WebP/JPEG jest nadal konieczny.
Pipeline krok po kroku – od audytu po monitoring
1. Audyt: znajdź element LCP
- PageSpeed Insights (mobilne): zanotuj element LCP oraz jego wagę.
 - WebPageTest → zakładka „Waterfall” – sprawdź, ile trwa pobieranie pliku i kiedy zostaje zainicjowane.
 - Jeżeli hero ładuje się dopiero po JS, usuń zależność od bundlera – obraz musi być w HTML.
 
2. Konwersja i nazewnictwo plików
- Użyj CLI (
squoosh-cli,sharp) lubSquoosh.appdo generowania AVIF/WebP. - Nazewnictwo: 
branża-lokalizacja-rozmiar.format(np.hydraulik-bytom-768.avif). - Parametry: AVIF q=0.5–0.6 (często 60-75% redukcji), WebP q=0.75.
 - Zostaw oryginał JPEG dla backupu i 
srcfallback. 
3. Przygotuj warianty rozmiarów
Standardowy set dla wizytówek (w px): 480, 768, 1024, 1440, 1920. Dzięki temu nie pobierasz 1920 px na ekranie telefonu.
4. Priorytetyzacja hero
- HTML: 
loading="eager",fetchpriority="high",decoding="async". - Head: preload dla głównego wariantu.
 
<link
  rel="preload"
  as="image"
  href="/images/hero-1440.avif"
  imagesrcset="/images/hero-768.avif 768w, /images/hero-1440.avif 1440w"
  imagesizes="(max-width: 768px) 92vw, 1200px"
  fetchpriority="high"
>
Uwaga: Preload ma sens tylko dla jednego, krytycznego obrazu. Nadmiar preloaderów konkuruje z fontami i CSS.
5. Obrazy „below the fold”
- Dodaj 
loading="lazy"orazfetchpriority="low". decoding="async"przyspiesza render.- Dla galerii → generuj miniatury (np. 320 px) i linkuj do pełnych rozmiarów.
 
6. Placeholder bez JavaScriptu
- Ustaw 
aspect-ratiow CSS lubwidth/heightw HTML. - Opcjonalnie: niskiej jakości placeholder (LQIP) jako 
background-colorlub data URI (ważący < 1 KB). - Brak JS = brak dodatkowych hydration islands.
 
7. Mapy, wideo, embed
- Zastąp iframe’y miniaturą: klik → dopiero wtedy wstawiasz 
<iframe>. - Mapę Google można zamienić na statyczny obraz SVG z zaznaczonym obszarem działania + przycisk „Otwórz trasę w Google Maps”.
 
8. Cache i CDN
- Hostuj obrazy na tym samym originie co strona (Astro + Cloudflare Pages/Netlify) – trywialny dostęp do cache.
 - Nagłówek: 
Cache-Control: public, max-age=31536000, immutable. - Przy aktualizacji – zmień nazwę pliku (
hero-v2-1440.avif). - W Cloudflare włącz Polish + WebP/AVIF w razie potrzeby (ale miej własne wersje dla pełnej kontroli).
 
9. Testy końcowe i monitoring
- Powtórz PageSpeed Insights (mobilne) – celem jest zielone LCP (< 2,5 s) i CLS < 0,1.
 - WebPageTest z konfiguracją „Slow 4G + Moto G Power” → sprawdź, czy obraz hero pobiera się w pierwszych 1,2 s.
 - Włącz Real User Monitoring (np. GDPRmetrics lub Cloudflare Web Analytics) i monitoruj rozkład LCP/INP z realnych wizyt.
 
Mini case study (anonimizowane)
Branża: usługi instalacyjne w Bytomiu
| Parametr | Przed (WordPress + slider) | Po (Astro + pipeline) | 
|---|---|---|
| Waga hero | 1,9 MB (JPEG) | 240 KB (AVIF + fallback) | 
| Largest Contentful Paint (mobil) | 3,7 s | 1,72 s | 
| Cumulative Layout Shift | 0,24 | 0,02 | 
| Zapytania z formularza / mies. | 11 | 28 | 
Kluczowe działania: usunięcie slidera, wygenerowanie 5 wariantów AVIF/WebP, preload hero, „click-to-load” dla mapy i filmu.
Checklist 15 minut przed publikacją
- ✅ Hero ma 
width/height,fetchpriority="high",loading="eager". - ✅ 
srcset+sizespokrywają mobil + desktop. - ✅ Preload tylko dla jednego obrazu hero.
 - ✅ Wszystkie obrazy mają AVIF/WebP + fallback JPEG/PNG.
 - ✅ Obrazy poniżej 1. ekranu mają 
loading="lazy"ifetchpriority="low". - ✅ Miniatury galerii ≤ 35 KB, pełne wersje otwierane w lightboxie lub nowej karcie.
 - ✅ Mapy/wideo renderują się dopiero po kliknięciu.
 - ✅ 
Cache-Controlustawiony na 1 rok zimmutable. - ✅ Wynik PSI (mobile) – LCP poniżej 2 s, CLS < 0,1.
 - ✅ Zapisz wyniki w arkuszu audytowym (łatwo porównać przy modernizacji).
 
FAQ – najczęstsze pytania klientów
Czy AVIF jest obowiązkowy?
Nie, ale w 2025 roku daje 20-35% mniejszą wagę niż WebP. Jeżeli generator nie wspiera AVIF, zacznij od WebP + JPEG fallback i zaplanuj migrację.
Ile wariantów obrazu muszę generować?
Zazwyczaj 4-5. Jeżeli sekcja ma maksymalną szerokość 960 px, nie potrzebujesz wersji 1920 px.
Czy fetchpriority="high" wpływa na SEO?
Pośrednio – Google mierzy LCP realnych użytkowników. Szybszy hero = lepsze CWV = lepsza widoczność lokalna.
img czy background-image w CSS?
Hero z treścią (nagłówek, CTA) zawsze jako <img> – łatwiej o alt, preload, optymalizację. background-image zostaw dla dekoracyjnych patternów.
Czy alt text i lazy loading wpływają na pozycje?
Tak. Opisy alternatywne wspierają SEO lokalne („hydraulik Bytom”) i dostępność. loading="lazy" nie obniża rankingów, o ile nie stosujesz go na elemencie LCP.
Masz już pipeline, który możesz wdrożyć w trakcie jednej popołudniowej modernizacji. Jeśli chcesz, żebym sprawdził Twoją stronę lub wdrożył AVIF/WebP w Twoim CMS-ie (Keystatic, Sanity, headless WordPress) – napisz, a przygotuję audyt Core Web Vitals dla Twojego biznesu.