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.