Wydajność obrazu

Obrazy są często największymnajczęściej występującym zasobem w internecie. Dzięki temu optymalizacja obrazów może znacznie zwiększyć skuteczność witryny. W większości przypadków optymalizacja obrazów oznacza skrócenie czasu przesyłania danych w sieci przez wysyłanie mniejszej liczby bajtów. Możesz też zoptymalizować liczbę bajtów wysyłanych do użytkownika, wyświetlając obrazy o rozmiarach odpowiednich dla jego urządzenia.

Obrazy można dodawać do strony za pomocą elementów <img> lub <picture> albo właściwości CSS background-image.

Rozmiar obrazu

Pierwszą optymalizacją, jaką możesz przeprowadzić w przypadku korzystania z zasobów obrazów, jest wyświetlanie obrazu w odpowiednim rozmiarze. W tym przypadku termin rozmiar odnosi się do wymiarów obrazu. Jeśli nie uwzględnimy innych zmiennych, obraz wyświetlany w kontenerze o wymiarach 500 x 500 pikseli będzie miał optymalny rozmiar 500 x 500 pikseli. Na przykład użycie kwadratowego obrazu o rozmiarze 1000 pikseli oznacza, że obraz jest 2 razy większy niż wymagany.

Jednak wybór odpowiedniego rozmiaru obrazu zależy od wielu zmiennych, co sprawia, że w każdym przypadku jest to dość skomplikowane. W 2010 r., kiedy pojawił się iPhone 4, rozdzielczość ekranu (640 x 960) była dwukrotnie większa niż w przypadku iPhone’a 3 (320 x 480). Jednak fizyczny rozmiar ekranu iPhone'a 4 pozostał w przybliżeniu taki sam jak w przypadku iPhone'a 3.

Wyświetlanie wszystkiego w wyższej rozdzielczości spowodowałoby znaczne zmniejszenie tekstu i obrazów – o połowę. Zamiast tego 1 piksel stał się 2 pikselami urządzenia. Jest to tzw. współczynnik pikseli urządzenia (DPR). iPhone 4 i wiele modeli iPhone'a wydanych po nim miały współczynnik DPR równy 2.

Wracając do wcześniejszego przykładu, jeśli urządzenie ma DPR 2, a obraz jest wyświetlany w kontenerze o wymiarach 500 x 500 pikseli, optymalny rozmiar to teraz kwadratowy obraz o wymiarach 1000 x 1000 pikseli (nazywany rozmiarem wewnętrznym). Podobnie, jeśli urządzenie ma DPR 3, optymalny rozmiar to kwadratowy obraz o rozmiarze 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 określone źródło obrazu musi zawierać adres URL obrazu oraz 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"
>

Powyższy fragment kodu HTML używa deskryptora gęstości pikseli, aby zasugerować przeglądarce użycie image-500.png na urządzeniach z wartością DPR 1, image-1000.jpg na urządzeniach z wartością DPR 2 i image-1500.jpg na urządzeniach z wartością DPR 3.

Chociaż może się to wydawać proste, DPR ekranu nie jest jedynym czynnikiem, który należy wziąć pod uwagę przy wyborze optymalnego obrazu dla danej strony. Kolejnym czynnikiem, który należy wziąć pod uwagę, jest układ strony.

sizes

Poprzednie rozwiązanie działa tylko wtedy, gdy obraz jest wyświetlany w tym samym rozmiarze pikseli CSS na wszystkich obszarach wyświetlania. W wielu przypadkach układ strony, a co za tym idzie rozmiar kontenera, zmienia się w zależności od urządzenia użytkownika.

Atrybut sizes umożliwia określenie zestawu rozmiarów źródła, z których każdy składa się z warunku dotyczącego multimediów i wartości. Atrybut sizes określa zamierzony rozmiar wyświetlania obrazu w pikselach CSS. W połączeniu z srcset deskryptorami szerokości przeglądarka może wybrać źródło obrazu, które najlepiej pasuje 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 powyższym fragmencie kodu HTML atrybut srcset określa listę kandydatów na obraz, z której przeglądarka może wybierać, rozdzielonych przecinkami. Każdy kandydat na liście składa się z adresu URL obrazu, a następnie ze składni oznaczającej wewnętrzną szerokość obrazu. Wymiary obrazu to jego rozmiar własny. Na przykład deskryptor 1000w oznacza, że wewnętrzna szerokość obrazu wynosi 1000 pikseli.

Na podstawie tych informacji przeglądarka ocenia warunek multimediów w atrybucie sizes i w tym przypadku otrzymuje instrukcję, że jeśli szerokość obszaru wyświetlania urządzenia przekracza 768 pikseli, obraz jest wyświetlany o szerokości 500 pikseli. Na mniejszych urządzeniach obraz jest wyświetlany w 100vw lub w pełnej szerokości widocznego obszaru.

Przeglądarka może następnie połączyć te informacje z listą srcsetźródeł obrazów, aby znaleźć optymalny obraz. Jeśli na przykład użytkownik korzysta z urządzenia mobilnego o szerokości ekranu 320 pikseli i współczynniku DPR 3, obraz jest wyświetlany w rozmiarze 320 CSS pixels x 3 DPR = 960 device pixels. W tym przykładzie najbliższy rozmiar obrazu to image-1000.jpg, który ma szerokość wewnętrzną 1000 pikseli (1000w).

Formaty plików

Przeglądarki obsługują kilka różnych formatów plików graficznych. Nowoczesne formaty obrazów, takie jak WebPAVIF, mogą zapewniać lepszą kompresję niż PNG lub JPEG, dzięki czemu rozmiar pliku obrazu jest mniejszy, a pobieranie trwa krócej. Wyświetlanie obrazów w nowoczesnych formatach może skrócić czas wczytywania zasobu, co może skutkować niższym wynikiem największego wyrenderowania treści (LCP).

WebP to powszechnie obsługiwany format, który działa we wszystkich nowoczesnych przeglądarkach. Format WebP często zapewnia lepszą kompresję niż JPEG, PNG czy GIF, oferując zarówno stratną, jak i bezstratną kompresję. WebP obsługuje też przezroczystość kanału alfa nawet w przypadku kompresji stratnej, co nie jest możliwe w przypadku kodeka JPEG.

AVIF to nowszy format obrazu, który nie jest tak powszechnie obsługiwany jak WebP, ale jest dość dobrze obsługiwany przez przeglądarki. Format AVIF obsługuje kompresję stratną i bezstratną, a testy wykazały, że w niektórych przypadkach pozwala on zaoszczędzić ponad 50% miejsca w porównaniu z formatem JPEG. Format AVIF oferuje też funkcje szerokiej gamy kolorów (WCG) i wysokiego zakresu dynamiki (HDR).

Kompresja

W przypadku obrazów istnieją 2 rodzaje kompresji:

  1. Kompresja stratna
  2. Kompresja bezstratna

Kompresja stratna polega na zmniejszeniu dokładności obrazu przez kwantyzację. Dodatkowe informacje o kolorach mogą być odrzucane przy użyciu próbkowania chrominancji. Kompresja stratna jest najbardziej skuteczna w przypadku obrazów o wysokiej gęstości z dużą ilością szumu i kolorów – zwykle zdjęć lub obrazów o podobnej zawartości. Dzieje się tak, ponieważ artefakty powstałe w wyniku kompresji stratnej są znacznie mniej widoczne na tak szczegółowych obrazach. Kompresja stratna może być jednak mniej skuteczna w przypadku obrazów zawierających ostre krawędzie, takich jak grafika liniowa, podobnie wyraźne szczegóły lub tekst. Kompresję stratną można zastosować 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 w stosunku do sąsiednich pikseli. Kompresja bezstratna jest używana w przypadku formatów GIF, PNG, WebP i AVIF.

Obrazy możesz skompresować za pomocą Squoosh, ImageOptim lub usługi optymalizacji obrazów. Podczas kompresji nie ma uniwersalnego ustawienia, które byłoby odpowiednie we wszystkich przypadkach. Zalecamy eksperymentowanie z różnymi poziomami kompresji, aż znajdziesz odpowiedni kompromis między jakością obrazu a rozmiarem pliku. Niektóre zaawansowane usługi optymalizacji obrazów mogą to zrobić automatycznie, ale mogą nie być opłacalne dla wszystkich użytkowników.

Element <picture>

Element <picture> zapewnia większą elastyczność w określaniu wielu kandydatów na obrazy:

<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 używasz elementów <source> w elemencie <picture>, możesz dodać obsługę obrazów AVIF i WebP, ale w przypadku, gdy przeglądarka nie obsługuje nowoczesnych formatów, możesz wrócić do bardziej kompatybilnych starszych formatów obrazów. W tym przypadku przeglądarka wybiera pierwszy pasujący element <source>. Jeśli może wyświetlić obraz w tym formacie, używa tego obrazu. W przeciwnym razie przeglądarka przechodzi do następnego określonego elementu <source>. W powyższym fragmencie kodu HTML format AVIF ma pierwszeństwo przed formatem WebP, a jeśli żaden z nich nie jest obsługiwany, używany jest format JPEG.

Element <picture> wymaga zagnieżdżonego elementu <img>. Atrybuty alt, width i height są zdefiniowane w <img> i używane niezależnie od wybranego <source>.

Element <source> obsługuje też atrybuty media, srcset i sizes. Podobnie jak w przypadku wcześniejszego przykładu <img>, te atrybuty wskazują przeglądarce, który obraz ma wybrać w przypadku różnych obszarów wyświetlania.

<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 dotyczący multimediów. W powyższym przykładzie DPR urządzenia jest używany jako warunek dotyczący multimediów. Każde urządzenie o współczynniku DPR większym lub równym 1,5 będzie używać pierwszego elementu <source>. Element <source> informuje przeglądarkę, że na urządzeniach z obszarem widocznym szerszym niż 768 pikseli wybrany kandydat na obraz jest wyświetlany w rozmiarze 500 pikseli szerokości. Na mniejszych urządzeniach zajmuje całą szerokość widocznego obszaru. Łącząc atrybuty media i srcset, możesz precyzyjniej określać, którego obrazu chcesz użyć.

Ilustruje to poniższa tabela, w której oceniono kilka szerokości obszaru wyświetlania i współczynników pikseli urządzenia:

Szerokość widocznego obszaru (w pikselach) 1 DPR 1,5 DPR 2 DPR 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 o współczynniku DPR 1 pobierają obraz image-500.jpg, w tym większość użytkowników komputerów, którzy wyświetlają obraz o zewnętrznym rozmiarze 500 pikseli szerokości. Z drugiej strony użytkownicy urządzeń mobilnych z wartością DPR 3 pobierają potencjalnie większy obrazimage-1500.jpg – ten sam, który jest używany na urządzeniach stacjonarnych z wartością DPR 3.

<picture>
  <source
    media="(min-width: 561px) 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> jest dostosowany tak, aby zawierał dodatkowy element <source>, który umożliwia używanie różnych obrazów na urządzeniach o wysokim współczynniku DPR:

Szerokość widocznego obszaru (w pikselach) 1 DPR 1,5 DPR 2 DPR 3 DPR
320 500.jpg 500.jpg 1000-sm.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 możesz zobaczyć, że image-1000-sm.jpg i image-1500-sm.jpg wyświetlają się w małych obszarach wyświetlania. Te dodatkowe informacje umożliwiają dalszą kompresję obrazów, ponieważ artefakty kompresji nie są zbyt widoczne przy tym rozmiarze i gęstości, a jednocześnie nie pogarszają jakości obrazu na urządzeniach stacjonarnych.

Możesz też uniknąć wyświetlania dużych obrazów w małych widocznych obszarach, dostosowując atrybuty srcsetmedia:

<picture>
  <source
    media="(min-width: 561px)"
    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 powyższym fragmencie kodu HTML deskryptory szerokości zostały zastąpione deskryptorami współczynnika pikseli urządzenia. Obrazy wyświetlane na urządzeniu mobilnym są ograniczone do /image-500.jpg lub /image-1000.jpg, nawet na urządzeniach z wartością DPR 3.

Jak zarządzać złożonością

Podczas pracy z obrazami elastycznymi możesz mieć wiele różnych wariantów rozmiaru i formatów każdego obrazu. W powyższym przykładzie używane są warianty dla każdego rozmiaru, ale z wyłączeniem formatów AVIF i WebP. Ile wariantów powinno być dostępnych? Podobnie jak w przypadku wielu problemów inżynieryjnych odpowiedź brzmi „to zależy”.

Chociaż może się wydawać, że im więcej odmian, tym lepiej, każda dodatkowa odmiana obrazu wiąże się z kosztami i mniej efektywnie wykorzystuje pamięć podręczną przeglądarki. W przypadku tylko 1 wersji każdy użytkownik otrzymuje ten sam obraz, więc można go bardzo wydajnie buforować.

Z drugiej strony, jeśli jest wiele odmian, każda z nich wymaga kolejnego wpisu w pamięci podręcznej. Koszty serwera mogą wzrosnąć, a wydajność może się obniżyć, jeśli wpis w pamięci podręcznej wariantu wygasł i trzeba ponownie pobrać obraz z serwera źródłowego.

Poza tym rozmiar dokumentu HTML rośnie z każdą odmianą. Może się okazać, że dla każdego obrazu wysyłasz wiele kilobajtów kodu HTML.

Wyświetlanie obrazów na podstawie nagłówka żądania Accept

Nagłówek żądania HTTP Accept informuje serwer, jakie typy treści są obsługiwane przez przeglądarkę użytkownika. Serwer może używać tych informacji do wyświetlania optymalnego formatu obrazu bez 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');

Powyższy fragment kodu HTML to uproszczona wersja kodu, który możesz dodać do backendu JavaScript na serwerze, aby wybierać i wyświetlać optymalny format obrazu. Jeśli nagłówek żądania Accept zawiera image/avif, wyświetlany jest obraz AVIF. W przeciwnym razie, jeśli nagłówek Accept zawiera image/webp, wyświetlany jest obraz WebP. Jeśli żaden z tych warunków nie jest spełniony, wyświetlany jest obraz JPEG.

Możesz modyfikować odpowiedzi na podstawie zawartości nagłówka żądania Accept na prawie każdym typie serwera WWW. Na przykład możesz przekształcać żądania obrazów na serwerach Apache na podstawie nagłówka Accept za pomocą mod_rewrite.

Nie różni się to od zachowania, które można zaobserwować w sieci dostarczania treści obrazów (CDN). Sieci CDN do obsługi obrazów to doskonałe rozwiązanie do optymalizacji obrazów i wysyłania optymalnego formatu w zależności od urządzenia i przeglądarki użytkownika.

Kluczem jest znalezienie równowagi, wygenerowanie rozsądnej liczby propozycji obrazów i zmierzenie wpływu na wrażenia użytkowników. Różne obrazy mogą dawać różne wyniki, a optymalizacje stosowane do poszczególnych obrazów zależą od ich rozmiaru na stronie i urządzeń używanych przez użytkowników. Na przykład baner powitalny o pełnej szerokości może wymagać więcej wariantów niż miniatury na stronie z informacjami o produkcie w e-commerce.

Leniwe ładowanie

Za pomocą atrybutu loading możesz poinformować przeglądarkę, że obrazy mają być wczytywane z opóźnieniem, gdy pojawią się w obszarze widocznym. Wartość atrybutu lazy informuje przeglądarkę, aby nie pobierała obrazu, dopóki nie znajdzie się on w obszarze widocznym (lub w jego pobliżu). Pozwala to zaoszczędzić przepustowość i umożliwia przeglądarce nadanie priorytetu zasobom potrzebnym do wyrenderowania najważniejszych treści, które są już widoczne.

decoding

Atrybut decoding informuje przeglądarkę, jak ma dekodować obraz. Wartość async informuje przeglądarkę, że obraz może być dekodowany asynchronicznie, co może skrócić czas renderowania innych treści. Wartość sync informuje przeglądarkę, że obraz powinien być wyświetlany w tym samym czasie co inne treści. Wartość domyślna auto pozwala przeglądarce zdecydować, co jest najlepsze dla użytkownika.

Wersje demonstracyjne obrazów

Sprawdź swoją wiedzę

Które formaty obrazów obsługują kompresję bezstratną?

GIF.
Dobrze!
JPEG.
Spróbuj ponownie.
PNG
Dobrze!
WebP.
Dobrze!
AVIF.
Dobrze!

Które formaty obrazów obsługują kompresję stratną?

GIF.
Spróbuj ponownie. Format GIF obsługuje tylko ograniczoną paletę 256 kolorów, ale kodowanie stratne musi zostać wykonane przed przekonwertowaniem pliku do formatu GIF.
JPEG.
Dobrze!
PNG
Spróbuj ponownie.
WebP.
Dobrze!
AVIF.
Dobrze!

Co deskryptor szerokości (np. 1000w) mówi przeglądarce o grafice określonej w atrybucie srcset?

Szerokość zewnętrzna obrazu, czyli wymiary obrazu w układzie po zastosowaniu stylów do strony.
Spróbuj ponownie.
Wewnętrzna szerokość obrazu, czyli jego wymiary.
Dobrze!

Co atrybut sizes mówi przeglądarce o elemencie <img>, do którego jest zastosowany?

Logika określająca, który kandydat podany w elemencie <img> srcset powinien zostać wczytany, biorąc pod uwagę wymiary bieżącego widocznego obszaru użytkownika.
Dobrze!
Wewnętrzna szerokość obrazu, który ma zostać wczytany z atrybutu srcset elementu <img>.
Spróbuj ponownie.

Dalej: wyniki filmu

Obrazy są najczęściej używanym typem multimediów w internecie, ale nie są jedynym, o którym musisz pamiętać, jeśli chodzi o wydajność. Filmy to kolejny popularny typ multimediów używany w internecie, który ma własne wymagania dotyczące skuteczności. W następnym module tego kursu poznasz techniki optymalizacji filmów i ich efektywnego wczytywania.