Wybierz odpowiedni poziom kompresji

Obrazy często stanowią większość pobranych bajtów ze strony internetowej i często zajmują znaczną ilość miejsca na stronie wizualnej. W efekcie optymalizacja obrazów może przynieść największe oszczędności bajtów i poprawić wydajność witryny: im mniej bajtów musi pobrać przeglądarka, tym mniej danych musi przesyłać klient, a im szybciej przeglądarka może pobierać i renderować przydatne treści na ekranie, tym lepiej.

Optymalizacja obrazów to zarówno sztuka, jak i nauka: sztuka, ponieważ nie ma jednej uniwersalnej odpowiedzi na pytanie, jak najlepiej skompresować pojedynczy obraz; nauka, ponieważ istnieje wiele dobrze opracowanych technik i algorytmów, które mogą znacznie zmniejszyć rozmiar obrazu. Określenie optymalnych ustawień obrazu wymaga dokładnej analizy wielu aspektów: możliwości formatu, treści zakodowanych danych, jakości, wymiarów w pikselach i innych.

Optymalizacja obrazów wektorowych

Wszystkie nowoczesne przeglądarki obsługują format SVG (Scalable Vector Graphics), który jest oparty na standardzie XML formatem obrazów dwuwymiarowych. Możesz osadzić znaczniki SVG bezpośrednio na stronie lub jako zasób zewnętrzny. Pliki SVG można tworzyć w większości programów do tworzenia grafik wektorowych. Można je też ręcznie napisać 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>

W powyższym przykładzie wyrenderowano prosty okrąg z czarnym konturem i czerwonym tłem. Obraz został wyeksportowany z programu Adobe Illustrator.

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

Jak widać, zawiera ono wiele metadanych, takich jak informacje o warstwach, komentarze i przestrzenie nazw XML, które często nie są potrzebne do renderowania zasobu w przeglądarce. Dlatego zawsze warto zminifikować pliki SVG, korzystając z narzędzia takiego jak SVGO.

W tym przypadku SVGO zmniejsza rozmiar powyższego pliku SVG wygenerowanego przez Illustratora o 58%, 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>

Ponieważ format SVG jest oparty na standardzie XML, możesz też zastosować kompresję GZIP, aby zmniejszyć rozmiar przesyłania. Upewnij się, że Twój serwer jest skonfigurowany tak, aby kompresować zasoby SVG.

Obraz rastrowy to po prostu dwuwymiarowa siatka pojedynczych „pikseli” – np. obraz o wymiarach 100 x 100 pikseli to sekwencja 10 000 pikseli. Każdy piksel przechowuje wartości „RGBA”: (R) czerwony, (G) zielony, (B) niebieski i (A) kanał alfa (przezroczystość).

Wewnętrznie przeglądarka przydziela 256 wartości (szarości) dla każdego kanału, co przekłada się na 8 bitów na kanał (2 ^ 8 = 256) oraz 4 bajty na piksel (4 kanały x 8 bitów = 32 bity = 4 bajty). Jeśli znamy wymiary siatki, możemy łatwo obliczyć rozmiar pliku:

  • Obraz o wymiarach 100 x 100 pikseli składa się z 10 tysięcy 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 x 100 pikseli może nie wydawać się dużym problemem, ale w przypadku większych obrazów rozmiar pliku szybko rośnie, co powoduje, że zasoby graficzne są pobierane powoli i kosztują dużo. Do tej pory w poście skupialiśmy się wyłącznie na obrazie „nieskompresowanym”. Na szczęście można zrobić wiele, aby zmniejszyć rozmiar pliku obrazu.

Jedną z prostych strategii jest zmniejszenie „głębi 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 łącznie. Co się stanie, jeśli zmniejszysz paletę do 256 kolorów? W tym przypadku na kanały RGB wystarczy łącznie 8 bitów, co oznacza natychmiastowe zaoszczędzenie 2 bajtów na piksel. To 50% oszczędności na kompresji w porównaniu z pierwotnym formatem 4 bajty na piksel.

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

Złożone sceny z łagodnymi przejściami kolorów (np. gradienty lub niebo) wymagają większych palet kolorów, aby uniknąć artefaktów wizualnych, takich jak piksele nieba w zasobie 5-bitowym. Z drugiej strony, jeśli obraz wykorzystuje tylko kilka kolorów, duża paleta jest po prostu marnowaniem cennych bitów.

Następnie, gdy zoptymalizujesz dane przechowywane w pojedynczych pikselach, możesz sięgnąć po bardziej zaawansowane metody i sprawdzać też piksele sąsiadujące:okazuje się, że wiele obrazów, a zwłaszcza zdjęć, ma wiele sąsiadujących pikseli o podobnych kolorach – na przykład niebo, powtarzające się tekstury itp. Korzystając z tych informacji, kompresor może zastosować kodowanie delty, w którym zamiast przechowywać poszczególne wartości każdego piksela, możesz przechowywać różnicę między sąsiednimi pikselami: jeśli sąsiednie piksele są takie same, deltą jest „zero” i wystarczy przechowywać tylko jeden bit. Ale dlaczego na tym poprzestać?

Oko ludzkie ma różny poziom wrażliwości na różne kolory: możesz zoptymalizować kodowanie kolorów, aby uwzględnić tę kwestię, 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 wykorzystać ten fakt, aby jeszcze bardziej ulepszyć kodowanie delty. Zamiast analizować tylko bezpośrednich sąsiadów każdego piksela, możesz analizować większe bloki sąsiednich pikseli i kodować różne bloki przy użyciu różnych ustawień.

Jak widzisz, optymalizacja obrazów szybko staje się skomplikowana (lub przyjemna, w zależności od punktu widzenia) i jest aktywną dziedziną badań naukowych i komercyjnych. Obrazy zajmują dużo miejsca, a rozwijanie lepszych technik kompresji obrazu jest bardzo opłacalne. Jeśli chcesz dowiedzieć się więcej, wejdź na stronę Wikipedii lub zapoznaj się z dokumentem na temat technik kompresji WebP.

Powtarzam, to świetna sprawa, ale i bardzo akademicki: w jaki sposób pomaga to w optymalizacji obrazów w witrynie? Ważne jest, aby zrozumieć charakter problemu: piksele RGBA, głębia bitowa i różne techniki optymalizacji. Przed omówieniem różnych formatów obrazów rastrowych należy zrozumieć i pamiętać o wszystkich tych pojęciach.

Bezstratna a stratna kompresja obrazu

W przypadku niektórych rodzajów danych, np. kodu źródłowego strony lub pliku wykonywalnego, kompresor nie może zmienić ani nie utracić żadnych oryginalnych informacji. Pojedynczy brakujący lub błędny fragment danych może całkowicie zmienić znaczenie zawartości pliku, a co gorsza nawet całkowicie go uszkodzić. W przypadku niektórych innych typów danych, takich jak obrazy, dźwięk i wideo, akceptowalne może być dostarczenie „przybliżonej” wersji danych źródłowych.

Działanie oka pozwala nam często rezygnować z pominięcia informacji o każdym pikselu w celu zmniejszenia rozmiaru pliku obrazu. Na przykład nasze oczy mają różną czułość na różne kolory, co oznacza, że do zakodowania niektórych kolorów możemy użyć mniejszej liczby bitów. W rezultacie typowy potok optymalizacji obrazu składa się z 2 podstawowych kroków:

  1. Obraz jest przetwarzany za pomocą filtra z utratą jakości, który eliminuje część danych pikseli.
  2. Obraz jest przetwarzany za pomocą filtra bezstratnego, który kompresuje dane pikseli.

Pierwszy krok jest opcjonalny, a dokładny algorytm zależy od konkretnego formatu obrazu. Należy jednak pamiętać, że każdy obraz może zostać poddany kompresji stratnej w celu zmniejszenia rozmiaru. Różnice między różnymi formatami obrazów, takimi jak GIF, PNG, JPEG i inne, wynikają z kombinacji konkretnych algorytmów używanych (lub pomijanych) podczas stosowania kroków stratnych i bezstratnych.

Jaka jest „optymalna” konfiguracja optymalizacji stratnej i bezstratnej? Odpowiedź zależy od zawartości obrazu i Twoich kryteriów, takich jak kompromis między rozmiarem pliku a artefaktami wprowadzanymi przez kompresję stratną: W niektórych przypadkach możesz pominąć optymalizację stratną, aby zachować pełną wierność szczegółów. W innych przypadkach możesz zastosować agresywną optymalizację stratną, aby zmniejszyć rozmiar pliku komponentu z obrazem. W tym przypadku musisz polegać na własnym osądzie i kontekście – nie ma jednego uniwersalnego ustawienia.

Przykładowo, gdy używasz formatu stratnego, takiego jak JPEG, kompresor zwykle udostępnia opcję „jakość” (np. suwak jakości w funkcji „Zapisz do internetu” w Adobe Photoshop), która jest zwykle liczbą od 1 do 100 kontrolującą wewnętrzne działanie określonej kolekcji algorytmów stratnych i bezstratnych. Aby uzyskać najlepsze wyniki, eksperymentuj z różnymi ustawieniami jakości obrazów. Nie bój się obniżyć jakości – efekty wizualne są często bardzo dobre, a oszczędności na rozmiarze pliku mogą być spore.

Wpływ kompresji obrazu na podstawowe wskaźniki internetowe

Ponieważ obrazy często kwalifikują się do największego wyrenderowania treści, skrócenie czasu wczytywania zasobów obrazu może poprawić LCP zarówno w laboratorium, jak i w sytuacji rzeczywistej.

Korzystając z ustawień kompresji w formatach obrazów rastrowych, eksperymentuj z formatami WebP i AVIF, aby sprawdzić, czy możesz przesłać ten sam obraz na mniejszym rozmiarze niż w przypadku starszych formatów.

Należy jednak uważać, aby nie nadmiernie kompresować obrazów rastrowych. Dobrym rozwiązaniem jest skorzystanie z CDN do optymalizacji obrazów, aby znaleźć najlepsze ustawienia kompresji, ale można też użyć narzędzi takich jak Butteraugli, aby oszacować różnice wizualne, dzięki czemu nie będziesz kodować obrazów zbyt agresywnie i nie stracisz zbyt wiele jakości.

Lista kontrolna optymalizacji obrazów

Oto kilka wskazówek i technik, o których warto pamiętać podczas optymalizacji obrazów:

  • Preferuj formaty wektorowe: obrazy wektorowe są niezależne od rozdzielczości i skali, dzięki czemu doskonale nadają się do stosowania na wielu urządzeniach i w wysokiej rozdzielczości.
  • Zmniejsz rozmiar i skompresuj zasoby SVG: znaczniki XML tworzone przez większość aplikacji do rysowania często zawierają niepotrzebne metadane, które można usunąć. Upewnij się, że serwery są skonfigurowane tak, aby stosować kompresję GZIP do zasobów SVG.
  • Wybieraj format WebP lub AVIF zamiast starszych formatów rastrowych: obrazy WebP i AVIF są zazwyczaj znacznie mniejsze niż obrazy w starszych formatach.
  • Wybieraj 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 – spora.
  • Usuń zbędne metadane obrazów: wiele obrazów rastrowych zawiera zbędne metadane zasobu, np. informacje geograficzne czy informacje o aparacie. Użyj odpowiednich narzędzi, aby usunąć te dane.
  • Udostępniaj obrazy pomniejszone: zmień rozmiar obrazów i upewnij się, że rozmiar „wyświetlania” jest 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 na każdym kroku: inwestuj w automatyczne narzędzia i infrastrukturę, które zapewnią, że wszystkie komponenty z obrazem będą zawsze optymalizowane.