Obrazy są często najwięcej i najpowszechniejszymi zasobami w internecie. W efekcie optymalizacja obrazów może znacznie zwiększyć skuteczność Twojej witryny. W większości przypadków optymalizacja obrazów oznacza skrócenie czasu działania sieci przez wysyłanie mniejszej liczby bajtów, ale można też zoptymalizować liczbę bajtów wysyłanych do użytkownika, wyświetlając obrazy w rozmiarze odpowiednim do urządzenia użytkownika.
Obrazy można dodawać do strony za pomocą elementów <img>
lub <picture>
albo właściwości background-image
CSS.
Rozmiar obrazu
Pierwszą optymalizacja, jaką można przeprowadzić, aby zacząć korzystać z zasobów graficznych, to wyświetlenie obrazu w odpowiednim rozmiarze. W tym przypadku termin size odnosi się do wymiarów obrazu. Nie uwzględniając żadnych innych zmiennych, optymalny rozmiar obrazu wyświetlany w kontenerze o wymiarach 500 x 500 pikseli powinien wynosić 500 x 500 pikseli. Na przykład obraz kwadratowy o powierzchni 1000 pikseli będzie 2 razy większy od potrzebnego.
Jednak na wybór odpowiedniego rozmiaru obrazu wpływa wiele zmiennych, przez co wybór właściwego rozmiaru w każdym przypadku jest dość skomplikowany. W 2010 roku, po wprowadzeniu iPhone'a 4, rozdzielczość ekranu (640 x 960) była dwukrotnie większa niż w iPhonie 3 (320 x 480). Jednak fizyczny rozmiar ekranu iPhone'a 4 pozostaje mniej więcej taki sam jak iPhone 3.
Wyświetlanie wszystkiego w wyższej rozdzielczości znacznie zmniejszyłoby tekst i obrazy – dokładnie o połowę poprzedniego rozmiaru. Jeden piksel stał się 2 pikselami urządzenia. Jest to tzw. współczynnik pikseli urządzeń (DPR). iPhone 4 i wiele późniejszych modeli iPhone'ów uzyskiwało 2DPR.
Wróćmy do poprzedniego przykładu. Jeśli urządzenie ma wartość DPR równą 2, a obraz jest wyświetlany w kontenerze o wymiarach 500 x 500 pikseli, optymalnym rozmiarem jest teraz kwadratowy obraz o wymiarach 1000 pikseli (nazywany rozmiarem wewnętrznym). Podobnie, jeśli wartość DPR urządzenia wynosi 3, optymalnym rozmiarem będzie kwadratowy obraz o wymiarach 1500 pikseli.
srcset
Element <img>
obsługuje atrybut srcset
, który umożliwia określenie listy możliwych źródeł obrazów, z których może korzystać przeglądarka. Każde podane źródło obrazu musi zawierać adres URL obrazu i deskryptor szerokości lub gęstości pikseli.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>
Poprzedni fragment kodu HTML korzysta z deskryptora gęstości pikseli, aby wskazać przeglądarce, że ma ona użyć wartości image-500.png
na urządzeniach z DPR 1, image-1000.jpg
na urządzeniach o wartości DPR 2 i image-1500.jpg
na urządzeniach o tej wartości 3.
Choć może się wydawać, że wszystko jest w porządku, DPR ekranu nie jest jedynym kwestią podczas wybierania optymalnego obrazu dla danej strony. Układ strony to kolejny element, który należy wziąć pod uwagę.
sizes
Poprzednie rozwiązanie działa tylko wtedy, gdy wyświetlasz obraz w tym samym rozmiarze w pikselach CSS we wszystkich widocznych obszarach. W wielu przypadkach układ strony i rozmiar kontenera zmieniają się w zależności od urządzenia użytkownika.
Atrybut sizes
umożliwia określenie zestawu rozmiarów źródeł, przy czym każdy rozmiar źródłowy składa się z warunku multimediów i wartości. Atrybut sizes
określa zamierzony rozmiar wyświetlanego obrazu w pikselach CSS. W połączeniu z deskryptorami szerokości srcset
przeglądarka może wybrać źródło obrazu najlepiej dostosowane do urządzenia użytkownika.
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
W poprzednim fragmencie kodu HTML atrybut srcset
określa listę rozdzielonych przecinkami grafik, które może wybrać przeglądarka. Każda propozycja na liście składa się z adresu URL obrazu, po którym następuje składnia oznaczająca jego wewnętrzną szerokość. Wewnętrzny rozmiar obrazu to jego wymiary. Na przykład deskryptor 1000w
wskazuje, że wewnętrzna szerokość obrazu ma 1000 pikseli.
Na podstawie tych informacji przeglądarka ocenia stan multimediów w atrybucie sizes
i – w tym przypadku – otrzymuje instrukcję, że jeśli szerokość widocznego obszaru na urządzeniu przekroczy 768 pikseli, obraz będzie wyświetlany o szerokości 500 pikseli. Na mniejszych urządzeniach obraz wyświetla się 100vw
lub całej szerokości widocznego obszaru.
Przeglądarka może następnie połączyć te informacje z listą źródeł obrazów srcset
, aby znaleźć optymalny obraz. Jeśli na przykład użytkownik korzysta z urządzenia mobilnego z ekranem o szerokości 320 pikseli i DPR równym 3, obraz jest wyświetlany tutaj: 320 CSS pixels x 3 DPR = 960 device pixels
. W tym przykładzie obraz o najbliższym rozmiarze to image-1000.jpg
, który ma wewnętrzną szerokość 1000 pikseli (1000w
).
Formaty plików
Przeglądarki obsługują kilka różnych formatów plików graficznych. Nowoczesne formaty obrazów, takie jak WebP i AVIF, mogą zapewniać lepszą kompresję niż PNG czy JPEG, dzięki czemu rozmiar pliku graficznego jest mniejszy, a jego pobieranie trwa krócej. Wyświetlając obrazy w nowoczesnych formatach, możesz skrócić czas wczytywania zasobów, przez co największe wyrenderowanie treści (LCP) może się zmniejszyć.
WebP to powszechnie obsługiwany format, który działa we wszystkich nowoczesnych przeglądarkach. WebP często ma lepszą kompresję niż JPEG, PNG i GIF, zapewniając zarówno kompresję stratną, jak i bezstratną. WebP obsługuje też przezroczystość kanału alfa nawet w przypadku kompresji stratnej – funkcji, której nie ma kodek JPEG.
Format AVIF to nowszy format obrazu, ale nie jest tak rozpowszechniony jak WebP, ale zapewnia przyzwoitą obsługę w różnych przeglądarkach. Format AVIF obsługuje zarówno kompresję stratną, jak i bezstratną. Testy wykazały w niektórych przypadkach ponad 50% oszczędności w porównaniu do plików JPEG. AVIF udostępnia też funkcje Wide Color Gamut (WCG) i High Dynamic Range (HDR).
Kompresja
Istnieją 2 rodzaje kompresji obrazów:
Kompresja stratna polega na ograniczaniu dokładności obrazu przez kwantyzację. Dodatkowe informacje o kolorach mogą być odrzucane, stosując podpróbkowanie kolorów. Kompresja stratna jest najskuteczniejsza w przypadku obrazów o dużej gęstości z dużą ilością szumu i kolorów, zwykle na zdjęciach i obrazach o podobnej zawartości. Dzieje się tak, ponieważ artefakty powstające w wyniku kompresji stratnej są znacznie mniej zauważone na tak szczegółowych obrazach. Kompresja stratna może być jednak mniej skuteczna w przypadku obrazów zawierających ostre krawędzie, takie jak grafika linii, mniej ostre szczegóły lub tekst. Kompresja stratna może być stosowana do obrazów JPEG, WebP i AVIF.
Kompresja bezstratna zmniejsza rozmiar pliku, kompresując obraz bez utraty danych. Kompresja bezstratna opisuje piksel na podstawie różnicy z sąsiadującymi z nim pikselami. Kompresja bezstratna jest używana w przypadku formatów GIF, PNG, WebP i AVIF.
Obrazy możesz skompresować za pomocą usług Squoosh, ImageOptim lub usługi optymalizacji obrazów. Nie ma uniwersalnego ustawienia, które sprawdzi się we wszystkich przypadkach. Zalecamy eksperymentowanie z różnymi poziomami kompresji, aż znajdziesz kompromis między jakością obrazu a rozmiarem pliku. Niektóre zaawansowane usługi optymalizacji obrazów mogą zrobić to za Ciebie automatycznie, ale mogą nie być opłacalne dla wszystkich użytkowników.
Element <picture>
Element <picture>
zapewnia większą elastyczność przy wskazywaniu kilku kandydujących obrazów:
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img
alt="An image"
width="500"
height="500"
src="/image.jpg"
>
</picture>
Gdy w elemencie <picture>
używasz elementów <source>
, możesz dodać obsługę obrazów w formacie AVIF i WebP, a jeśli przeglądarka nie obsługuje nowoczesnych formatów, wrócić do bardziej zgodnych starszych formatów graficznych. W ten sposób przeglądarka wybiera pierwszy pasujący element <source>
. Jeśli może wyrenderować obraz w tym formacie, użyje tego obrazu. W przeciwnym razie przeglądarka przechodzi do następnego określonego elementu <source>
. W poprzednim fragmencie kodu HTML format AVIF ma wyższy priorytet niż WebP i wybiera format JPEG, jeśli nie jest obsługiwany format AVIF ani WebP.
Element <picture>
wymaga umieszczonego w nim elementu <img>
. Atrybuty alt
, width
i height
są zdefiniowane w <img>
i używane niezależnie od tego, która wartość <source>
jest wybrana.
Element <source>
obsługuje też atrybuty media
, srcset
i sizes
. Podobnie jak w przypadku poprzedniego przykładu <img>
, wskazują one przeglądarce, który obraz ma być wybierany w różnych widocznych obszarach.
<picture>
<source
media="(min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
Atrybut media
przyjmuje warunek mediów. W poprzednim przykładzie jako warunek dotyczący multimediów jest używany DPR urządzenia. Wszystkie urządzenia o wartości DPR większej lub równej 1,5 będą używać pierwszego elementu <source>
. Element <source>
informuje przeglądarkę, że na urządzeniach o szerokości widocznego obszaru większej niż 768 pikseli wybrany kandydujący obraz jest wyświetlany o szerokości 500 pikseli. Na mniejszych urządzeniach zajmuje to całą szerokość widocznego obszaru. Dzięki połączeniu atrybutów media
i srcset
masz większą kontrolę nad tym, którego obrazu użyć.
Widać to w tabeli poniżej, w której ocenianych jest kilka szerokości widocznego obszaru i różnych współczynników pikseli urządzenia:
Szerokość widocznego obszaru (w pikselach) | 1 DPR | 1,5 DPR | 2 KD | 3 DPR |
---|---|---|---|---|
320 | 500.jpg | 500.jpg | 500.jpg | 1000.jpg |
480 | 500.jpg | 500.jpg | 1000.jpg | 1500.jpg |
560 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
Urządzenia z numerem DPR 1 pobierają obraz image-500.jpg
. Dotyczy to także większości użytkowników komputerów, którzy widzą obraz w rozmiarze zewnętrznym wynoszącym 500 pikseli. Z drugiej strony użytkownicy urządzeń mobilnych o DPR równy 3 pobierają potencjalnie większą wartość image-1500.jpg
– to samo zdjęcie co na komputerach z DPR równym 3.
<picture>
<source
media="(min-width: 560px) and (min-resolution: 1.5x)"
srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<source
media="(max-width: 560px) and (min-resolution: 1.5x)"
srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
sizes="(min-width: 768px) 500px, 100vw"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
W tym przykładzie element <picture>
został dostosowany tak, aby zawierał dodatkowy element <source>
, który pozwala używać różnych obrazów w przypadku szerokich urządzeń o wysokiej wartości DPR:
Szerokość widocznego obszaru (w pikselach) | 1 DPR | 1,5 DPR | 2 KD | 3 DPR |
---|---|---|---|---|
320 | 500.jpg | 500.jpg | 500.jpg | 1000-sm.jpg |
480 | 500.jpg | 500.jpg | 1000-sm.jpg | 1500-sm.jpg |
560 | 500.jpg | 1000-sm.jpg | 1000-sm.jpg | 1500-sm.jpg |
1024 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
1920 | 500.jpg | 1000.jpg | 1000.jpg | 1500.jpg |
Dzięki temu dodatkowemu zapytaniu widać, że image-1000-sm.jpg
i image-1500-sm.jpg
są wyświetlane na małych widocznych obszarach. Te dodatkowe informacje pozwalają jeszcze bardziej skompresować obrazy. Artefakty kompresji przy takim rozmiarze i gęstości nie są dobrze widoczne. Nie wpływają też na jakość obrazu na komputerach.
Możesz też dostosować atrybuty srcset
i media
, aby uniknąć wyświetlania dużych obrazów w małych widocznych obszarach:
<picture>
<source
media="(min-width: 560px)"
srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x"
>
<source
media="(max-width: 560px)"
srcset="/image-500.jpg 1x, /image-1000.jpg 2x"
>
<img
alt="An image"
width="500"
height="500"
src="/image-500.jpg"
>
</picture>
W poprzednim fragmencie kodu HTML deskryptory szerokości zostały usunięte na rzecz deskryptorów współczynnika pikseli urządzenia. Zdjęcia wyświetlane na urządzeniach mobilnych mogą być ograniczone do /image-500.jpg
lub /image-1000.jpg
, nawet na urządzeniach o wartości DPR równej 3.
Jak radzić sobie ze złożonością
Podczas pracy z obrazami elastycznymi można stosować wiele różnych rozmiarów i formatów dla każdego obrazu. W poprzednim przykładzie używane są odmiany każdego rozmiaru, ale wykluczają one formaty AVIF i WebP. Ile wariantów trzeba postawić? Podobnie jak w przypadku wielu problemów inżynieryjnych, odpowiedź zwykle brzmi: „to zależy”.
Zastosowanie jak największej liczby odmian obrazu w celu uzyskania najlepszego dopasowania może być kuszące, ale każdy dodatkowy wariant obrazów jest droższy i ogranicza wykorzystanie pamięci podręcznej przeglądarki. W przypadku tylko jednego wariantu każdy użytkownik otrzymuje ten sam obraz, więc można go bardzo wydajnie buforować.
Z drugiej strony jeśli występuje wiele odmian, każdy z nich wymaga osobnego wpisu w pamięci podręcznej. Koszty serwera mogą wzrosnąć i zmniejszyć wydajność, jeśli wpis w pamięci podręcznej wariantu wygasł i będzie trzeba ponownie pobrać obraz z serwera pierwotnego.
Poza tym rozmiar dokumentu HTML zwiększa się z każdą wersją. Może się okazać, że w przypadku każdego obrazu przesyłasz kilka kilobajtów kodu HTML.
Wyświetlaj obrazy na podstawie nagłówka żądania Accept
Nagłówek żądania HTTP Accept
informuje serwer, które typy treści może rozpoznawać przeglądarka użytkownika. Dzięki tym informacjom serwer może wyświetlać obraz w optymalnym formacie bez konieczności dodawania dodatkowych bajtów do odpowiedzi HTML.
if (request.headers.accept) {
if (request.headers.accept.includes('image/avif')) {
return reply.from('image.avif');
} else if (request.headers.accept.includes('image/webp')) {
return reply.from('image.webp');
}
}
return reply.from('image.jpg');
Poprzedni fragment kodu HTML to uproszczona wersja kodu, którą możesz dodać do backendu JavaScript serwera, aby wybrać i wyświetlać obraz w optymalnym formacie.
Jeśli nagłówek Accept
żądania zawiera element image/avif
, wyświetlany jest obraz AVIF. W przeciwnym razie, jeśli nagłówek Accept
zawiera element image/webp
, wyświetlany jest obraz WebP. Jeśli żaden z tych warunków nie jest spełniony, wyświetla się obraz JPEG.
Możesz modyfikować odpowiedzi na podstawie zawartości nagłówka żądania Accept
na niemal każdym typie serwera WWW – na przykład przepisywać żądania obrazów na serwerach Apache na podstawie nagłówka Accept
za pomocą mod_rewrite
.
Działa to podobnie do sieci dystrybucji treści graficznych (CDN). Sieci CDN z obrazami to świetne rozwiązania do optymalizowania obrazów i wysyłania optymalnego formatu w zależności od urządzenia i przeglądarki użytkownika.
Najważniejsze jest znalezienie równowagi, wygenerowanie rozsądnej liczby pasujących obrazów i zmierzenie wpływu na wrażenia użytkownika. Różne obrazy przynoszą różne wyniki, a optymalizacje zastosowane do każdego z nich zależą od rozmiaru obrazu na stronie oraz od urządzeń, z których korzystają użytkownicy. Na przykład baner powitalny o pełnej szerokości może wymagać większej liczby wariantów niż miniatury na stronie z informacjami o produkcie w e-commerce.
Leniwe ładowanie
Można użyć atrybutu loading
, aby nakazać przeglądarce leniwe ładowanie obrazów, gdy pojawią się one w widocznym obszarze. Wartość atrybutu lazy
informuje przeglądarkę, aby nie pobierała obrazu, dopóki nie znajdzie się on w widocznym obszarze (lub w jego pobliżu). Oszczędza to przepustowość, dzięki czemu przeglądarka może priorytetowo traktować zasoby potrzebne do wyrenderowania kluczowych treści, które znajdują się już w widocznym obszarze.
decoding
Atrybut decoding
informuje przeglądarkę, jak ma zdekodować obraz. Wartość async
informuje przeglądarkę, że obraz można dekodować asynchronicznie, co może skrócić czas renderowania innych treści. Wartość sync
informuje przeglądarkę, że obraz powinien być prezentowany w tym samym czasie co inne treści.
Dzięki domyślnej wartości auto
przeglądarka może zdecydować, co jest najlepsze dla użytkownika.
Wersje demonstracyjne
Sprawdź swoją wiedzę
Które formaty obrazów obsługują kompresję bezstratną?
Które formaty obrazów obsługują kompresję stratną?
Co deskryptor szerokości (np. 1000w
) informuje przeglądarkę o proponowanym obrazie określonym w atrybucie srcset
?
Co atrybut sizes
informuje przeglądarkę o elemencie <img>
, do którego jest stosowany?
srcset
elementu <img>
powinien zostać wczytany, z uwzględnieniem wymiarów bieżącego widocznego obszaru użytkownika.
srcset
elementu <img>
.
Następny temat: wyniki filmów
Obrazy są najpowszechniejszym rodzajem multimediów wykorzystywanych w internecie, ale są daleko od jedynego, o którym musisz pamiętać, jeśli chodzi o skuteczność. Filmy to kolejny często spotykany typ mediów w internecie, który ma swoje własne parametry działania. W następnym module tego kursu poznasz techniki optymalizacji filmów i ich efektywne wczytywanie.