Obrazy w wysokiej rozdzielczości dla zmiennej gęstości pikseli

Jedną z funkcji współczesnych złożonych urządzeń jest bardzo szeroki zakres gęstości pikseli ekranu. Niektóre urządzenia mają wyświetlacze o bardzo wysokiej rozdzielczości, a inne mają problemy z tyłem. Deweloperzy aplikacji muszą obsługiwać różną gęstość pikseli, co może stanowić spore wyzwanie. W przypadku internetu mobilnego trudności podlegają kilku czynnikom:

  • Szeroki wybór urządzeń o różnych formatach.
  • Ograniczona przepustowość sieci i żywotność baterii.

W przypadku obrazów celem deweloperów aplikacji internetowych jest jak najefektywniejsze wyświetlanie obrazów najwyższej jakości. W tym artykule omówimy kilka przydatnych technik, które mogą się przydać dziś i w niedalekiej przyszłości.

Jeśli to możliwe, unikaj obrazów

Zanim otworzysz tę puszkę robaków, zwróć uwagę, że internet zawiera wiele zaawansowanych technologii, które w dużej mierze zależą od rozdzielczości i DPI. W szczególności tekst, SVG i znaczna część elementów CSS będą „po prostu działać” dzięki funkcji automatycznego skalowania pikseli w internecie (za pomocą devicePixelRatio).

Jednak nie zawsze można uniknąć obrazów rastrowych. Możesz na przykład otrzymać zasoby, które byłyby trudne do powielenia w czystej postaci SVG/CSS, albo mieć do czynienia ze zdjęciem. Można automatycznie przekonwertować obraz do SVG, ale wektorowywanie zdjęć nie ma sensu, ponieważ skalowane wersje zwykle nie wyglądają dobrze.

Wprowadzenie

Bardzo krótka historia gęstości wyświetlania

Na początku gęstość pikseli na wyświetlaczach komputerowych wynosiła 72 lub 96 dpi (kropki na cal).

Gęstość pikseli na wyświetlaczach stopniowo się zmniejszała. Zdecydowaliśmy się na to w dużej mierze z powodu zastosowania urządzeń mobilnych, w których użytkownicy zazwyczaj zbliżają telefony do twarzy, dzięki czemu piksele są lepiej widoczne. W 2008 r. telefony z rozdzielczością 150 dpi były nową normą. Trend zwiększonej gęstości wyświetlaczy był kontynuowany, a dzisiejsze nowe telefony są wyposażone w ekrany o rozdzielczości 300 dpi (firmy Apple „Retina”).

Święty Graal to oczywiście wyświetlacz, w którym piksele są całkowicie niewidoczne. Jeśli chodzi o format telefonu, bieżąca generacja wyświetlaczy Retina/HiDPI może być bliska takiego idealnego. Jednak nowe klasy sprzętu i urządzeń do noszenia, takie jak Project Glass, będą prawdopodobnie nadal zwiększać gęstość pikseli.

W praktyce obrazy o niskiej gęstości powinny wyglądać na nowych ekranach tak samo, jak na starych, ale w porównaniu z ostrymi obrazami o dużej gęstości obrazy o niskiej gęstości wyglądają irytują i są pikselizowane. Poniżej przedstawiono przybliżoną symulację wyglądu obrazu 1x na wyświetlaczu 2x. Natomiast obraz 2x wygląda całkiem nieźle.

Pawian 1x
Pawian 2x
Paczki! o różnej gęstości pikseli.

Piksele w internecie

W momencie projektowania internetu 99% wyświetlaczy miało rozdzielczość 96 dpi (lub mialiśmy tę sytuację) i niewiele przepisów dotyczących tego aspektu było możliwe. Ze względu na dużą zmienność ekranów o różnej gęstości i/lub wielkości ekranu potrzebowaliśmy standardowego sposobu na zapewnienie dobrego wyglądu obrazów przy różnych gęstościach i wymiarach ekranu.

Specyfikacja HTML rozwiązała ostatnio ten problem, definiując piksel referencyjny, którego producenci używają do określania rozmiaru piksela CSS.

Za pomocą piksela referencyjnego producent może określić rozmiar fizycznego piksela urządzenia w odniesieniu do piksela standardowego lub idealnego. Jest to tzw. współczynnik pikseli urządzenia.

Obliczanie współczynnika pikseli urządzenia

Załóżmy, że smartfon ma ekran z fizycznym ekranem o rozdzielczości 180 pikseli na cal (ppi). Obliczanie współczynnika pikseli urządzenia składa się z 3 kroków:

  1. Porównaj rzeczywistą odległość, w jakiej utrzymuje się urządzenie, z odległością piksela referencyjnego.

    Ze specyfikacji wiemy, że przy 28 calach wartość idealna to 96 pikseli na cal. Ponieważ jest to smartfon, ludzie trzymają go bliżej twarzy niż laptopa. Oszacujmy tę odległość na 18 cali.

  2. Pomnóż współczynnik odległości przez gęstość standardową (96 ppi), aby uzyskać idealną gęstość pikseli dla danej odległości.

    idealna gęstość pikseli = (28/18) * 96 = 150 pikseli na cal (w przybliżeniu)

  3. Dopasuj współczynnik fizycznej gęstości pikseli do idealnej gęstości pikseli, aby uzyskać współczynnik pikseli urządzenia.

    devicePixelRatio = 180/150 = 1,2

Sposób obliczania parametru devicePixelRatio.
Wykres przedstawiający 1 odnośny kątowy piksel, który ułatwia zilustrowanie sposobu obliczania wartości parametru devicePixelRatio.

Teraz, gdy przeglądarka musi wiedzieć, jak zmienić rozmiar obrazu, aby dopasować go do ekranu zgodnie z idealną lub standardową rozdzielczością, używa ona współczynnika piksela na poziomie 1,2, co oznacza, że każdy idealny piksel urządzenia ma 1,2 piksela fizycznego. Wzór na rozdzielenie pikseli idealnych (zgodnie ze specyfikacją internetową) i fizycznych (kropki na ekranie urządzenia) wygląda tak:

physicalPixels = window.devicePixelRatio * idealPixels

W przeszłości dostawcy urządzeń zaokrąglali je do devicePixelRatios. iPhone i iPad firmy Apple – DPR 1, a retina – 2. Specyfikacja CSS zaleca,

Jednostka pikselowa odnosi się do pełnej liczby pikseli urządzenia, której najlepiej odpowiadają pikselowi referencyjnemu.

Jednym z powodów, dla których proporcje są lepsze, jest to, że mogą one prowadzić do mniejszej liczby artefaktów podpikseli.

Rzeczywistość związana z urządzeniami jest jednak znacznie bardziej zróżnicowana, a telefony z Androidem często mają DPR równy 1, 5. Wartość DPR tabletu Nexus 7 wynosi ok.1,33, co obliczono według obliczeń podobnych do powyższego. W przyszłości możemy się spodziewać większej liczby urządzeń ze zmiennymi wartościami DPR. Dlatego nigdy nie zakładaj, że Twoi klienci będą mieli całkowite DPR.

Omówienie technik przetwarzania obrazu HiDPI

Jest wiele technik, które pozwalają rozwiązać problem jak najszybszego wyświetlania zdjęć o najwyższej jakości. Ogólnie można podzielić się na 2 kategorie:

  1. Optymalizacja pojedynczych obrazów
  2. Optymalizacja wyboru między wieloma obrazami.

Podejście z jednym obrazem: wykorzystaj jeden obraz, ale zastosuj z nim coś sprytnego. Takie metody mają tę wadę, że trzeba obniżyć wydajność, ponieważ obrazy w formacie HiDPI będą pobierane nawet na starszych urządzeniach, które mają niższą rozdzielczość. Oto kilka rozwiązań w przypadku zgłoszeń z jednym obrazem:

  • Mocno skompresowany obraz HiDPI
  • Wyjątkowo niesamowity format obrazu
  • Format obrazu progresywnego

Różne sposoby użycia obrazów: używaj wielu obrazów, ale zastanów się, który z nich ma być ładowany. Twórcy i deweloperzy muszą najpierw opracować kilka wersji tego samego zasobu, a potem opracować strategię decyzyjną. Dostępne opcje to:

  • JavaScript
  • Dostarczanie po stronie serwera
  • Zapytania o media CSS
  • Wbudowane funkcje przeglądarki (image-set(), <img srcset>)

Mocno skompresowany obraz HiDPI

Obrazy generują już aż 60% przepustowości na pobieranie przeciętnej witryny. Wyświetlając obrazy HiDPI wszystkim klientom, zwiększymy tę liczbę. O ile będzie większy?

Wykonałem testy, które wygenerowały fragmenty obrazów 1 x i 2 razy w jakości JPEG 90, 50 i 20. Oto skrypt powłoki, którego użyłem do ich wygenerowania (za pomocą ImageMagick):

Przykładowe kafelki 1. Przykładowe kafelki 2. Przykładowe kafelki 3.
Próbki obrazów o różnej kompresji i różnej gęstości pikseli.

Z tego małego, nienaukowego próbkowania wynika, że kompresja dużych obrazów daje dobre wyniki w zakresie stosunku jakości do rozmiaru. Mocno skompresowane zdjęcia 2x wyglądają lepiej niż nieskompresowane zdjęcia 1x.

Oczywiście serwowanie dwukrotnie skompresowanych obrazów o niskiej jakości na 2 urządzeniach jest gorsze niż udostępnianie plików wyższej jakości. Za takie działanie możemy nałożyć karę za jakość obrazu. Jeśli porównamy jakość: 90 obrazów do jakości: 20 obrazów, pojawi się spadek ostrości i zwiększonej ziarnistości. Artefakty te mogą nie być akceptowane w przypadkach, gdy kluczowe są obrazy wysokiej jakości (np. w aplikacji do przeglądania zdjęć), lub gdy deweloperzy aplikacji nie chcą iść na kompromis.

Powyższe porównanie zostało wykonane w całości ze skompresowanych plików JPEG. Warto zauważyć, że między powszechnie stosowanymi formatami obrazów (JPEG, PNG, GIF) występują wiele kompromisów, które skłaniają nas do...

Wyjątkowo niesamowity format obrazu

WebP to dość interesujący format obrazów, który bardzo się kompresuje, zachowując wysoką jakość obrazu. Oczywiście nie wszędzie jest ona stosowana.

Jednym ze sposobów jest sprawdzenie, czy obsługa protokołu WebP jest obsługiwana, za pomocą JavaScriptu. Wczytujesz obraz o rozmiarze 1 piksela za pomocą identyfikatora data-uri, czekasz na uruchomienie zdarzeń załadowania lub zdarzeń błędu, a potem sprawdzasz, czy jego rozmiar jest prawidłowy. Modernizr wykorzystuje taki skrypt wykrywania cech, który jest dostępny w aplikacji Modernizr.webp.

Lepszym sposobem jest jednak użycie funkcji image() bezpośrednio w CSS. Jeśli więc masz obraz WebP i zastępczą plik JPEG, możesz napisać:

#pic {
  background: image("foo.webp", "foo.jpg");
}

Istnieje kilka problemów z tym podejściem. Po pierwsze, właściwość image() nie jest w ogóle wdrożona na szeroką skalę. Po drugie, mimo że kompresja WebP wydobywa z wody JPEG dane, nadal osiąga się coraz słabsze wyniki, o około 30% mniejsze na podstawie danych z tej galerii WebP. Dlatego sama wersja WebP nie wystarczy do rozwiązania problemu o wysokiej wartości DPI.

Progresywne formaty obrazu

Progresywne formaty obrazów, takie jak JPEG 2000, progresywne JPEG, progresywne PNG i GIF, mają (trochę dyskutowaną) tę zaletę, że obraz pojawiają się przed jego pełnym wczytaniem. Może się to wiązać z pewnymi kosztami, chociaż istnieją sprzeczne dowody. Jeff Atwood twierdzi, że tryb progresywny „zwiększa rozmiar obrazów PNG o około 20% i o około 10% do rozmiaru obrazów JPEG i GIF”. Stoyan Stefanov twierdzi jednak, że w większości przypadków w przypadku dużych plików tryb progresywny jest bardziej wydajny.

Na pierwszy rzut oka obrazy progresywne wyglądają bardzo obiecująco, ponieważ umożliwiają jak najszybsze wyświetlanie zdjęć najlepszej jakości. Oznacza to, że przeglądarka może zatrzymać pobieranie i dekodowanie obrazu, gdy wie, że dodatkowe dane nie poprawią jakości obrazu (tzn. wszystkie ulepszenia jakości dotyczą pikseli podrzędnych).

Połączenia można łatwo zakończyć, ale ponowne uruchomienie jest często kosztowne. W przypadku witryny z wieloma obrazami najwydajniejszym sposobem jest utrzymanie aktywnego połączenia HTTP i używanie go jak najdłużej. Jeśli połączenie zostanie przerwane przedwcześnie z powodu wystarczającego pobrania jednego obrazu, przeglądarka musi utworzyć nowe połączenie. Może to być naprawdę wolne przy niewielkich opóźnieniach.

Jednym z rozwiązań tego problemu jest użycie żądania Zakres HTTP, które umożliwia przeglądarkom określenie zakresu bajtów do pobrania. Inteligentna przeglądarka może wysłać żądanie HEAD, aby uzyskać nagłówek, przetworzyć go, zdecydować, ile obrazu jest faktycznie potrzebnych, a następnie je pobrać. Zakres HTTP jest jednak słabo obsługiwany przez serwery WWW, przez co takie podejście jest niepraktyczne.

Oczywistym ograniczeniem takiego podejścia jest to, że nie można wybierać obrazu do wczytania, a jedynie różne poziomy jakości tego samego obrazu. Dlatego nie dotyczy to przypadku użycia funkcji „kierunek artystyczny”.

Użyj JavaScriptu do określenia, który obraz wczytać

Pierwszym i najbardziej oczywistym podejściem do wybierania obrazu do wczytania jest użycie JavaScriptu w kliencie. Dzięki temu dowiesz się wszystkiego o kliencie użytkownika i wykonasz właściwe działania. Możesz określić współczynnik pikseli urządzenia za pomocą funkcji window.devicePixelRatio, uzyskać szerokość i wysokość ekranu, a nawet spróbować przechwycić połączenia sieciowe przez navigator.connection lub wysłać fałszywe żądanie, tak jak robi to biblioteka foresight.js. Po zebraniu wszystkich tych informacji zdecyduj, który obraz wczytać.

Istnieje około miliona bibliotek JavaScript, które działają w sposób podobny do tego, ale żadna z nich nie wyróżnia się szczególnie.

Jedną z dużych wad tego podejścia jest to, że używanie JavaScriptu powoduje opóźnienie wczytywania obrazu do momentu zakończenia działania parsera podglądowego. Oznacza to, że pobieranie obrazów rozpocznie się dopiero po uruchomieniu zdarzenia pageload. Więcej na ten temat znajdziesz w artykule Jasona Grigsby'ego.

Zdecyduj, który obraz ma zostać wczytany na serwerze

Możesz odroczyć decyzję po stronie serwera, określając niestandardowe moduły obsługi żądań dla każdego wyświetlanego obrazu. Taki moduł obsługiwałby obsługę Retina na podstawie klienta użytkownika (jedynego przekazywanego do serwera informacji). Następnie w zależności od tego, czy logika po stronie serwera ma wyświetlać zasoby HiDPI, wczytujesz odpowiedni zasób (nazwany zgodnie ze znaną konwencją).

Niestety parametr User-Agent nie zawsze dostarcza wystarczająco dużo informacji, aby można było zdecydować, czy urządzenie ma otrzymywać obrazy o wysokiej czy niskiej jakości. Nie da się też zaznaczyć, że wszystko, co jest związane z User-Agentem, jest błędem i w miarę możliwości należy go unikać.

Używanie zapytań o media CSS

Dzięki deklaratywnemu zapytaniu o media CSS możesz wyrazić swoje intencje i pozwolić przeglądarce robić to za Ciebie. Oprócz najczęstszego użycia zapytań o multimedia – dopasowania do rozmiaru urządzenia – możesz też dopasować typ devicePixelRatio. Powiązane zapytanie o media to device-pixel-ratio z powiązanymi minimalnymi i maksymalnymi wariantami. Jeśli chcesz wczytywać obrazy o wysokiej rozdzielczości, a współczynnik pikseli urządzenia przekracza określony próg, możesz wykonać te czynności:

#my-image { background: (low.png); }

@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

To trochę skomplikowane, gdy pomieszane są wszystkie prefiksy dostawców, zwłaszcza z powodu szalonych różnic w ich umiejscowieniu: „min” i „max”:

@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {

  #my-image {
    background:url(high.png);
  }
}

Dzięki temu odzyskujesz korzyści płynące z analizowania od razu, które zostały utracone w ramach rozwiązania JS. Zyskujesz też elastyczność wybierania elastycznych punktów przerwania (np. możesz mieć obrazy o niskiej, średniej i wysokiej wartości DPI), co zostało utracone w przypadku metody po stronie serwera.

Niestety narzędzie nadal jest trochę nieporęczne i prowadzi do dziwnego wyglądu CSS (lub wymaga wstępnego przetworzenia). Ta metoda jest ograniczona do właściwości CSS, więc nie ma możliwości ustawienia atrybutu <img src> i wszystkie obrazy muszą być elementami z tłem. Jeśli będziesz ograniczać się tylko do współczynnika pikseli urządzenia, może się zdarzyć, że smartfon o wysokiej rozdzielczości pobierze ogromny zasób graficzny podwójnie przy połączeniu EDGE. Nie jest to najdogodniejsze rozwiązanie dla użytkowników.

Korzystanie z nowych funkcji przeglądarki

Ostatnio ostatnio toczy się wiele tematów o obsłudze przez platformy internetowe problemu z obrazem w wysokiej rozdzielczości DPI. Niedawno włamał się do tej przestrzeni Apple, wprowadzając do WebKit funkcję CSS image-set(). Tak więc obsługują ją zarówno Safari, jak i Chrome. To funkcja CSS, więc image-set() nie rozwiązuje problemu z tagami <img>. Wpisz @srcset, który rozwiązuje ten problem, ale (w momencie tworzenia tego tekstu) nie ma jeszcze implementacji referencyjnej. W następnej sekcji opisujemy szczegółowo image-set i srcset.

Funkcje przeglądarki umożliwiające obsługę wysokiej rozdzielczości DPI

Decyzja o tym, którą strategię należy zastosować, zależy od Twoich konkretnych wymagań. Pamiętaj przy tym, że wszystkie wspomniane rozwiązania mają wady. Rozwiązanie tego problemu będzie można jednak rozwiązać, gdy zaczną być powszechnie obsługiwane zasoby image-set i srcset. Tymczasem omówmy kilka sprawdzonych metod, które mogą przybliżyć nas do tej idealnej przyszłości.

Po pierwsze: czym się różnią te dwie usługi? image-set() to funkcja CSS, która można wykorzystać jako wartość właściwości CSS tła.srcset to atrybut charakterystyczny dla elementów <img> o podobnej składni. Oba te tagi umożliwiają określenie deklaracji obrazów, ale atrybut srcset pozwala też skonfigurować, który obraz ma być wczytywany w zależności od rozmiaru widocznego obszaru.

Sprawdzone metody dotyczące ustawiania obrazów

Funkcja CSS image-set() jest dostępna z prefiksem -webkit-image-set(). Składnia jest dość prosta, ponieważ wymaga podania co najmniej 1 deklaracji obrazu rozdzielonej przecinkami, która składa się z ciągu adresu URL lub funkcji url(), po których następuje powiązana rozdzielczość. Na przykład:

background-image:  -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

Informuje ona przeglądarkę, że mają do wyboru 2 obrazy. Jeden jest zoptymalizowany pod kątem wyświetlaczy 1x, a drugi pod kątem wyświetlaczy 2x. Następnie przeglądarka wybiera, która z nich ma wczytać, na podstawie różnych czynników, takich jak szybkość sieci, o ile jest wystarczająco inteligentna (o ile nie jest jeszcze zaimplementowane).

Oprócz wczytania właściwego obrazu przeglądarka będzie go też odpowiednio skalować. Inaczej mówiąc, przeglądarka zakłada, że 2 obrazy są 2 razy większe od obrazów 1x, więc skaluje obraz podwójnie w dół 2-krotnie, tak by na stronie miał ten sam rozmiar.

Zamiast 1x, 1, 5x lub Nx możesz też określić gęstość pikseli urządzenia w dpi.

Działa to dobrze, z wyjątkiem przeglądarek, które nie obsługują właściwości image-set, ponieważ w takim przypadku obraz w ogóle nie jest wyświetlany. To oczywista niekorzystna sytuacja, więc musisz użyć kreacji zastępczej (lub serii wartości zastępczych), aby rozwiązać ten problem:

background-image: url(icon1x.jpg);
background-image: -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);
/* This will be useful if image-set gets into the platform, unprefixed.
    Also include other prefixed versions of this */
background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

Powyższe powoduje załadowanie odpowiedniego zasobu w przeglądarkach, które obsługują zestaw obrazów, i zastępowanie zasobu 1x. Wyraźnym zastrzeżeniem jest to, że chociaż obsługa image-set() w przeglądarkach nie jest obsługiwana, większość klientów użytkownika otrzyma zasób 1x.

Ta wersja demonstracyjna używa metody image-set(), aby wczytać prawidłowy obraz, a jeśli ta funkcja CSS nie jest obsługiwana, powraca do zasobu 1x.

Być może zastanawiasz się teraz, dlaczego nie użyć kodu polyfill (czyli utworzyć podkładkę podkładek dla JavaScriptu) image-set() i nadać mu 1 dzień. Jak się okazuje, trudno jest wdrożyć efektywne kody polyfill w funkcjach CSS. (szczegółowe wyjaśnienia znajdziesz w tej dyskusji na temat www-style).

Zbiór zasobów obrazu

Oto przykład obiektu srcset:

<img alt="my awesome image"
  src="banner.jpeg"
  srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">

Jak widać, oprócz deklaracji x podanych przez image-set element srcset przyjmuje również wartości W i H odpowiadające rozmiarowi widocznego obszaru, starając się wyświetlać najtrafniejszą wersję. Powyższy kod wyświetlałby baner-phone.jpeg na urządzeniach o szerokości widocznego obszaru poniżej 640 pikseli, baner-phone-HD.jpeg na małym ekranie urządzenia o wysokiej rozdzielczości DPI, banner-HD.jpeg na urządzeniach o wysokiej rozdzielczości DPI dla ekranów większych niż 640 px oraz banner.jpeg na wszystkich pozostałych urządzeniach.

Używanie obrazu ustawionego dla elementów graficznych

Ponieważ atrybut srcset elementów img nie jest zaimplementowany w większości przeglądarek, kuszące może być zastąpienie elementów img elementami <div> tłem i stosowanie podejścia do ustawiania obrazów. Będzie to działać, z zastrzeżeniami. Wadą tego rozwiązania jest to, że tag <img> ma długą wartość semantyczną. W praktyce jest to szczególnie ważne w przypadku robotów sieciowych i ułatwień dostępu.

Jeśli w końcu użyjesz właściwości -webkit-image-set, być może zechcesz użyć właściwości CSS tła. Wadą tego podejścia jest to, że musisz określić rozmiar obrazu, który jest nieznany w przypadku korzystania z obrazu innego niż 1x. Zamiast tego możesz użyć właściwości CSS content w ten sposób:

<div id="my-content-image"
  style="content: -webkit-image-set(
    url(icon1x.jpg) 1x,
    url(icon2x.jpg) 2x);">
</div>

Spowoduje to automatyczne przeskalowanie obrazu na podstawie parametru devicePixelRatio. Zapoznaj się z tym przykładem przedstawioną wyżej technikę w praktyce, z dodatkową wartością zastępczą url() w przypadku przeglądarek, które nie obsługują image-set.

Zbiór źródłowy Polyfilling

Przydatną funkcją srcset jest to, że ma ona naturalną wartość zastępczą. Jeśli atrybut srcset nie jest zaimplementowany, wszystkie przeglądarki muszą przetworzyć ten atrybut. Poza tym, ponieważ to tylko atrybut HTML, można tworzyć kody polyfill z JavaScriptem.

Ten kod polyfill obejmuje testy jednostkowe, dzięki którym możesz mieć pewność, że jest jak najbardziej zbliżona do specyfikacji. Obowiązują też mechanizmy kontroli, które uniemożliwiają kodowi polyfill wykonanie kodu, jeśli atrybut srcset jest zaimplementowany natywnie.

Oto prezentacja, jak działa polyfill.

Podsumowanie

Nie istnieje cudowny sposób na rozwiązanie problemu obrazów o wysokiej rozdzielczości DPI.

Najłatwiejszym rozwiązaniem jest całkowite wykluczenie z obrazów i wykorzystanie w zamian SVG i CSS. Jednak nie zawsze jest to realne, zwłaszcza jeśli w Twojej witrynie znajdują się obrazy wysokiej jakości.

Podejścia w języku JS i CSS oraz po stronie serwera mają swoje mocne i słabe strony. Najbardziej obiecujące jest jednak wykorzystanie nowych funkcji przeglądarek. Choć funkcje image-set i srcset w przeglądarkach nadal nie są obsługiwane, możesz skorzystać z rozsądnych rozwiązań zastępczych.

Oto moje zalecenia: