Wybierz odpowiedni poziom kompresji

Obrazy często odpowiadają za większość pobranych bajtów ze strony internetowej i często zajmują sporo miejsca na ekranie. W rezultacie optymalizacja obrazów często przynosi największe korzyści w zakresie oszczędności i wydajności witryny: im mniej bajtów musi pobierać przeglądarka, tym mniejsza konkurencja w zakresie przepustowości klienta i tym szybciej może pobierać i renderować przydatne treści na ekranie.

Optymalizacja obrazów to zarówno sztuka, jak i nauka. sztuka, bo nie ma jednego uniwersalnego sposobu na skompresowanie pojedynczego obrazu, a nauka, ponieważ istnieje wiele dobrze rozwiniętych technik i algorytmów, które mogą znacznie zmniejszyć rozmiar obrazu. Ustalenie optymalnych ustawień obrazu wymaga dokładnej analizy wielu wymiarów, m.in. możliwości formatu, treści kodowanych danych, jakości i wymiarów w pikselach.

Optymalizacja obrazów wektorowych

Wszystkie nowoczesne przeglądarki obsługują grafikę Scalable Vector Graphics (SVG), czyli format XML do tworzenia grafiki dwuwymiarowej. Znaczniki SVG możesz umieścić bezpośrednio na stronie lub jako zasób zewnętrzny. Większość oprogramowania do rysowania wektorowego pozwala tworzyć pliki SVG lub tworzyć je ręcznie bezpośrednio w ulubionym edytorze tekstu.

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.2" baseProfile="tiny" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
    x="0px" y="0px" viewBox="0 0 612 792" xml:space="preserve">
<g id="XMLID_1_">
  <g>
    <circle fill="red" stroke="black" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/>
  </g>
</g>
</svg>

Powyższy przykład renderuje poniższy prosty okrąg z czarnym konturem i czerwonym tłem oraz został wyeksportowany z programu Adobe Illustrator.

<?xml version="1.0" encoding="utf-8"?>

Jak widać, zawiera on wiele metadanych, takich jak informacje o warstwie, komentarze i przestrzenie nazw XML, które często nie są potrzebne do renderowania zasobu w przeglądarce. Dlatego zawsze warto zmniejszyć pliki SVG za pomocą takiego narzędzia jak SVGO.

Na przykład SVGO zmniejsza rozmiar powyższego pliku SVG wygenerowanego w programie Illustrator o 58%, zmniejszając jego rozmiar z 470 do 199 bajtów.

<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 792"><circle fill="red" stroke="#000" stroke-width="2" stroke-miterlimit="10" cx="50" cy="50" r="40"/></svg>

SVG to format oparty na XML, więc możesz też użyć kompresji GZIP, by zmniejszyć rozmiar przesyłanych plików – sprawdź, czy Twój serwer jest skonfigurowany tak, by kompresować zasoby SVG.

Obraz rastrowy to po prostu dwuwymiarowa siatka pojedynczych „pikseli” – na przykład obraz o wymiarach 100 × 100 pikseli to ciąg 10 000 pikseli. Każdy piksel z kolei przechowuje wartości „RGBA”: kanał czerwony (R), kanał zielony (G), kanał niebieski (B) i kanał (A) alfa (przejrzystość).

Wewnętrznie przeglądarka przydziela 256 wartości (cieni) do każdego kanału, co oznacza 8 bitów na kanał (2 ^ 8 = 256) i 4 bajty na piksel (4 kanały x 8 bitów = 32 bity = 4 bajty). Dzięki temu, jeśli znamy wymiary siatki, możemy łatwo obliczyć rozmiar pliku:

  • Obraz o wymiarach 100 × 100 pikseli składa się z 10 tys. pikseli.
  • 10 000 pikseli x 4 bajty = 40 000 bajtów
  • 40 000 bajtów / 1024 = 39 KB
Wymiary Piksele Rozmiar pliku
100 x 100 10 000 39 KB
200 x 200 40 000 156 KB
300 x 300 pikseli 90 000 351 KB
500 x 500 250 000 977 KB
800 x 800 640 000 2500 KB

39 KB w przypadku obrazu o wymiarach 100 × 100 pikseli może nie wydawać się niczym dużym, ale w przypadku większych obrazów rozmiar pliku szybko się eksploduje, przez co pobieranie komponentów z obrazem jest powolne i kosztowne. Do tej pory ten post skupiał się tylko na „nieskompresowanym” formacie obrazu. Na szczęście można zrobić wiele rzeczy, aby zmniejszyć rozmiar pliku.

Prosta strategia polega na ograniczeniu „głębokości bitowej” obrazu z 8 bitów na kanał do mniejszej palety kolorów. 8 bitów na kanał daje nam 256 wartości na kanał i 16 777 216 (256 ^ 3) kolorów w sumie. A jeśli zmniejszysz paletę do 256 kolorów? W takim przypadku potrzebujesz łącznie tylko 8 bitów dla kanałów RGB i natychmiast można zaoszczędzić 2 bajty na piksel – to 50% oszczędności w porównaniu z oryginalnym formatem 4 bajtów na piksel.

Artefakty kompresji
Od lewej do prawej (PNG): 32-bitowa (16 mln kolorów), 7-bitowa (128 kolorów), 5-bitowa (32 kolory).

Złożone sceny ze stopniowymi zmianami barw (np. gradienty lub niebo) wymagają większej palety kolorów, aby uniknąć efektów wizualnych, takich jak pikselizowane niebo w 5-bitowym zasobie. Z drugiej strony, jeśli na obrazie jest tylko kilka kolorów, duża paleta po prostu marnuje cenne kawałki.

Następnie, po zoptymalizowaniu danych przechowywanych w poszczególnych pikselach, możesz dokładniej przyjrzeć się sąsiednim pikselem: na całym świecie wiele obrazów, a zwłaszcza zdjęcia, ma wiele pobliskich pikseli o podobnych kolorach, np. niebo, powtarzające się tekstury itd. Korzystając z tych informacji, kompresor może zastosować kodowanie delta, w którym zamiast przechowywać osobne wartości dla każdego piksela, możesz zapisać różnicę między sąsiednimi pikselami. Jeśli sąsiednie piksele są takie same, delta ma wartość „0” i wystarczy zapisać tylko jeden bit. Ale nie poprzestawaj na tym...

Ludzkie oko ma różny poziom czułości na różne kolory: możesz zoptymalizować kodowanie kolorów, zmniejszając lub zwiększając paletę tych kolorów. Piksele „W pobliżu” tworzą dwuwymiarową siatkę. Oznacza to, że każdy piksel ma wielu sąsiadów: możesz to wykorzystać do dalszego ulepszania kodowania delta. Zamiast patrzeć tylko na sąsiadów każdego piksela, możesz przyjrzeć się większym blokom sąsiednich pikseli i zakodować różne bloki z różnymi ustawieniami.

Jak widać, optymalizacja obrazów szybko staje się skomplikowana (lub zabawna, w zależności od punktu widzenia), i jest aktywnym obszarem badań akademickich i komercyjnych. Obrazy zajmują dużo bajtów, dlatego warto rozwijać lepsze techniki kompresji obrazów. Jeśli chcesz dowiedzieć się więcej, wejdź na stronę Wikipedii lub przeczytaj dokument o technikach kompresji WebP, aby zapoznać się z praktycznym przykładem.

Rozumiem, że to świetnie, ale też materiał akademicki: w jaki sposób pomaga to w optymalizacji obrazów w witrynie? Trzeba zrozumieć kształt problemu: piksele RGBA, głębia bitowa i różne techniki optymalizacji. Wszystkie te pojęcia należy zrozumieć i pamiętać o nich przed rozpoczęciem dyskusji na temat różnych formatów obrazów rastrowych.

Bezstratna lub stratna kompresja obrazu

W przypadku niektórych rodzajów danych, np. kodu źródłowego strony czy pliku wykonywalnego, bardzo ważne jest, aby kompresor nie mógł zmienić ani nie utracić żadnych oryginalnych informacji. Pojedynczy brakujący lub niewłaściwy fragment danych może całkowicie zmienić znaczenie zawartości pliku lub, co gorsza, całkowicie je uszkodzić. W przypadku niektórych innych rodzajów danych, takich jak obrazy, dźwięki i filmy, reprezentowanie „przybliżonych” danych oryginalnych jest całkowicie akceptowalne.

Z uwagi na sposób działania oka możemy często pomijać część informacji o każdym pikselu, aby zmniejszyć rozmiar pliku. Na przykład nasze oczy mają różną czułość reagowania na różne kolory, co oznacza, że do zakodowania niektórych kolorów mamy mniej bitów. W efekcie typowy proces optymalizacji obrazów składa się z 2 ogólnych kroków:

  1. Obraz jest przetwarzany za pomocą filtra pozbawionego, który eliminuje część danych pikselowych.
  2. Obraz jest przetwarzany za pomocą filtra bezstratnego, który kompresuje dane piksela.

Pierwszy krok jest opcjonalny, a dokładny algorytm będzie zależał od konkretnego formatu obrazu. Warto jednak pamiętać, że każdy obraz może zostać poddany stratnej kompresji w celu zmniejszenia jego rozmiaru. W rzeczywistości różnica między różnymi formatami obrazów, np. GIF, PNG, JPEG i innymi, polega na połączeniu konkretnych algorytmów, które używają (lub pomijają) podczas stosowania kroków stratnych i bezstratnych.

Jaka jest więc „optymalna” konfiguracja optymalizacji bezstratnej i stratnej? Odpowiedź zależy od zawartości obrazu i Twoich własnych kryteriów, takich jak kompromis między rozmiarem pliku a artefaktami wynikającymi z kompresji stratnej. W niektórych przypadkach możesz pominąć optymalizację stratną, aby przekazać skomplikowane szczegóły z pełną wiernością. W innych przypadkach można zastosować agresywną optymalizację stratną, aby zmniejszyć rozmiar pliku komponentu z obrazem. W tym przypadku musisz wziąć pod uwagę Twój osąd i kontekst – nie ma jednego uniwersalnego ustawienia.

Praktyczny przykład: gdy używasz formatu stratnego, takiego jak JPEG, kompresor zwykle wyświetla dostosowywane ustawienie „jakości” (np. suwak jakości dostępny w ramach funkcji „Zapisz w internecie” w programie Adobe Photoshop), które zwykle zawiera liczbę z zakresu od 1 do 100, która kontroluje działanie określonego zbioru algorytmów stratnych i bezstratnych. Aby uzyskać najlepsze wyniki, eksperymentuj z różnymi ustawieniami jakości obrazów i nie bój się obniżyć ich jakości. Wyniki wizualne są często bardzo dobre, a rozmiar pliku może być spory.

Wpływ kompresji obrazów na podstawowe wskaźniki internetowe

Obrazy często są kandydatami do największego wyrenderowania treści, dlatego skrócenie czasu ładowania obrazu może przełożyć się na lepszy LCP zarówno w module, jak i w polu.

Podczas eksperymentowania z ustawieniami kompresji obrazów rastrowych poeksperymentuj z formatami WebP i AVIF, aby sprawdzić, czy uda Ci się przesłać ten sam obraz przy użyciu mniejszej liczby obrazów w porównaniu ze starszymi formatami.

Uważaj jednak, aby nie nadmiernie kompresować obrazów rastrowych. Dobrym rozwiązaniem jest użycie sieci CDN do optymalizacji obrazów, aby znaleźć najlepsze ustawienia kompresji. Zamiast tego możesz też skorzystać z narzędzi takich jak Butteraugli do oszacowania różnic wizualnych. W ten sposób unikniesz zbyt agresywnego kodowania obrazów i utracisz zbyt dużą jakość obrazów.

Lista kontrolna optymalizacji obrazu

Oto wskazówki i techniki, o których warto pamiętać podczas optymalizacji obrazów:

  • Wybieraj formaty wektorowe: obrazy wektorowe są niezależne od rozdzielczości i skali, co sprawia, że idealnie sprawdzają się na wielu urządzeniach i w wysokiej rozdzielczości.
  • Zmniejszaj i kompresuj zasoby SVG: znaczniki XML tworzone w większości aplikacji do rysowania zawierają często niepotrzebne metadane, które można usunąć. Upewnij się, że Twoje serwery są skonfigurowane do stosowania kompresji GZIP zasobów SVG.
  • Preferuj WebP lub AVIF zamiast starszych formatów rastrowych: obrazy WebP i AVIF są zwykle znacznie mniejsze niż starsze formaty obrazów.
  • Wybierz najlepszy format obrazów rastrowych: ustal wymagania funkcjonalne i wybierz taki, który pasuje do poszczególnych zasobów.
  • Eksperymentuj z optymalnymi ustawieniami jakości formatów rastrowych: nie bój się obniżyć ustawień jakości. Efekty są często bardzo dobre, a oszczędność bajtów – znaczna.
  • Usuń zbędne metadane obrazu: wiele obrazów rastrowych zawiera zbędne metadane zasobu, takie jak informacje geograficzne, informacje o aparacie itp. Użyj odpowiednich narzędzi, aby pozbyć się tych danych.
  • Wyświetlaj skalowane obrazy: zmień rozmiar obrazów i zadbaj o to, aby rozmiar „wyświetlany” był jak najbardziej zbliżony do „naturalnego” rozmiaru obrazu. Zwróć szczególną uwagę na duże obrazy, ponieważ to one są największym obciążeniem po zmianie rozmiaru.
  • Automatyzacja i automatyzacja: zainwestuj w zautomatyzowane narzędzia i infrastrukturę, które zagwarantują ciągłe optymalizowanie wszystkich komponentów z obrazem.