Obrazy — największy ciężar Twojej strony
Według HTTP Archive obrazy stanowią średnio 40-50% wagi strony internetowej. Na typowej stronie firmowej to kilka megabajtów grafik — zdjęcia zespołu, portfolio, tła sekcji, ikony. Każdy kilobajt to czas ładowania, zużycie transferu mobilnego i potencjalnie stracony użytkownik.
Dobra wiadomość: optymalizacja obrazów to jedno z najłatwiejszych i najskuteczniejszych działań przyspieszających stronę. Odpowiedni format, kompresja i lazy loading mogą zmniejszyć wagę grafik o 60-80% bez widocznej utraty jakości.
JPEG, PNG, WebP, AVIF — przegląd formatów
JPEG to weteran formatu stratnego, idealny do fotografii. Kompresja jest regulowana (zwykle 75-85% jakości daje dobry balans). Wada: nie obsługuje przezroczystości i przy wysokiej kompresji pojawiają się charakterystyczne artefakty.
PNG to format bezstratny, idealny do grafik z ostrymi krawędziami, tekstu i przezroczystości. Wada: pliki są znacznie większe niż JPEG dla fotografii. PNG nie powinno się używać do zdjęć — to częsty błąd, który niepotrzebnie obciąża stronę.
WebP to format opracowany przez Google, dostępny od 2010 roku. Wspiera zarówno kompresję stratną (lepsza od JPEG o 25-35%), jak i bezstratną (lepsza od PNG o 25%). Obsługuje przezroczystość i animacje. W 2024 roku jest wspierany przez wszystkie główne przeglądarki, włącznie z Safari (od wersji 14, 2020).
AVIF (AV1 Image File Format) to najnowszy format, oparty na kodeku wideo AV1. Oferuje jeszcze lepszą kompresję niż WebP — oszczędność 20-30% względem WebP przy porównywalnej jakości. Świetnie radzi sobie z fotografiami i obsługuje HDR. Wsparcie przeglądarek jest już szerokie: Chrome (od 2020), Firefox (od 2021), Safari (od 2023).
Porównanie kompresji — konkretne liczby
Weźmy typowe zdjęcie (1920x1080, fotografia):
| Format | Jakość | Rozmiar | Oszczędność vs JPEG | |---|---|---|---| | JPEG 80% | Dobra | 250 KB | — | | WebP 80% | Dobra | 170 KB | 32% | | AVIF 60% | Dobra | 120 KB | 52% |
Przy 20 zdjęciach na stronie różnica między samym JPEG a AVIF to 2,6 MB mniej do pobrania. Na wolnym połączeniu mobilnym to kilka sekund szybszego ładowania.
Jak serwować nowoczesne formaty
Problem: nie wszystkie przeglądarki wspierają AVIF (choć wsparcie rośnie). Rozwiązanie: element <picture> w HTML pozwala zdefiniować kilka źródeł, a przeglądarka wybierze najlepsze:
<picture>
<source srcset="zdjecie.avif" type="image/avif">
<source srcset="zdjecie.webp" type="image/webp">
<img src="zdjecie.jpg" alt="Opis zdjęcia" width="800" height="600">
</picture>
Przeglądarka próbuje źródeł od góry: jeśli wspiera AVIF, pobierze .avif. Jeśli nie, spróbuje WebP. Jeśli nie wspiera żadnego z nowoczesnych formatów, użyje klasycznego JPEG. To progresywne ulepszenie — każdy użytkownik zobaczy zdjęcie, ale ci z nowszymi przeglądarkami dostaną lżejszą wersję.
Alternatywne podejście to negocjacja po stronie serwera — Nginx może sprawdzać nagłówek Accept i serwować odpowiedni format. Ale podejście z <picture> jest prostsze i nie wymaga konfiguracji serwera.
Responsywne obrazy z srcset
Oprócz formatu ważny jest też rozmiar. Nie ma sensu wysyłać obrazu 2000px na telefon z ekranem 400px:
<img
srcset="zdjecie-400.webp 400w,
zdjecie-800.webp 800w,
zdjecie-1200.webp 1200w,
zdjecie-1600.webp 1600w"
sizes="(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
800px"
src="zdjecie-800.webp"
alt="Opis zdjęcia"
width="800"
height="600"
>
Atrybut srcset podaje dostępne rozmiary, a sizes informuje przeglądarkę, ile miejsca zajmie obraz na ekranie. Przeglądarka sama wybiera optymalny rozmiar, uwzględniając gęstość pikseli (Retina) i szerokość viewportu.
Lazy loading — ładuj tylko to, co widoczne
Lazy loading to technika opóźniania ładowania obrazów, które nie są jeszcze widoczne na ekranie. Użytkownik widzi natychmiast zawartość "above the fold", a obrazy dalej na stronie ładują się dopiero, gdy użytkownik do nich przewinie.
Najprosztsza implementacja — natywny atrybut HTML:
<img src="zdjecie.webp" alt="Opis" loading="lazy" width="800" height="600">
Atrybut loading="lazy" jest wspierany przez wszystkie nowoczesne przeglądarki. Przeglądarka sama decyduje, kiedy zacząć ładować obraz, bazując na odległości od viewportu.
Ważne zasady:
- Nie stosuj lazy loading dla obrazów above the fold — pierwszy widoczny obraz (np. hero image) powinien ładować się natychmiast. Użyj
loading="eager"lub po prostu pomiń atrybut - Zawsze podawaj width i height — bez wymiarów przeglądarka nie może zarezerwować miejsca i obrazy będą "skakać" podczas ładowania (problemy z CLS)
- Rozważ
fetchpriority="high"— dla najważniejszego obrazu na stronie (np. LCP element) ten atrybut informuje przeglądarkę o priorytecie
Narzędzia do konwersji i optymalizacji
Squoosh (squoosh.app) — przeglądarkowe narzędzie Google do porównywania formatów i regulowania kompresji. Idealne do pojedynczych obrazów.
ImageMagick / libvips — narzędzia wiersza poleceń do masowej konwersji:
# Konwersja JPEG na WebP
cwebp -q 80 zdjecie.jpg -o zdjecie.webp
# Konwersja na AVIF
avifenc --min 20 --max 30 zdjecie.jpg zdjecie.avif
Sharp (Node.js) — biblioteka do przetwarzania obrazów po stronie serwera, wykorzystująca libvips. Wydajna i wygodna w automatyzacji.
Checklist optymalizacji obrazów
- Konwertuj zdjęcia na WebP (i opcjonalnie AVIF) z odpowiednią kompresją
- Przygotuj warianty rozmiarowe dla responsywnego serwowania
- Użyj
<picture>lubsrcsetdo serwowania odpowiedniego formatu i rozmiaru - Dodaj
loading="lazy"do obrazów poniżej linii zaginania - Zawsze podawaj
widthiheightw atrybutach - Ustaw
fetchpriority="high"dla obrazu LCP - Skonfiguruj cache HTTP dla plików graficznych (np.
Cache-Control: max-age=31536000)
Podsumowanie
Optymalizacja obrazów to nisko wiszący owoc wydajności stron WWW. Przejście z JPEG na WebP/AVIF, responsywne rozmiary i lazy loading mogą zmniejszyć wagę strony o ponad połowę. Narzędzia są darmowe, implementacja prosta, a efekty natychmiastowe — zarówno w metrykach Core Web Vitals, jak i w realnym doświadczeniu użytkowników.