Eines der Merkmale der heutigen komplexen Gerätelandschaft ist, dass es eine sehr große Bandbreite an Bildschirmpixeldichten gibt. Einige Geräte haben sehr hochauflösende Displays, während andere hinterherhinken. Anwendungsentwickler müssen eine Vielzahl von Pixeldichten unterstützen, was ziemlich schwierig sein kann. Im mobilen Web werden die Herausforderungen durch mehrere Faktoren verschärft:
- Große Vielfalt an Geräten mit unterschiedlichen Formfaktoren.
- Eingeschränkte Netzwerkbandbreite und Akkulaufzeit
Bei Bildern ist das Ziel von Web-App-Entwicklern, Bilder in der bestmöglichen Qualität möglichst effizient bereitzustellen. In diesem Artikel werden einige nützliche Methoden beschrieben, die Sie heute und in naher Zukunft anwenden können.
Vermeiden Sie nach Möglichkeit Bilder.
Bevor Sie diese Büchse der Pandora öffnen, denken Sie daran, dass das Web viele leistungsstarke Technologien bietet, die weitgehend unabhängig von Auflösung und DPI sind. Insbesondere Text, SVG und ein Großteil von CSS funktionieren aufgrund der automatischen Pixel-Skalierung des Webs (über devicePixelRatio) „einfach so“.
Allerdings lassen sich Rasterbilder nicht immer vermeiden. Möglicherweise haben Sie beispielsweise Assets, die sich nur schwer in reiner SVG-/CSS-Form nachbilden lassen, oder Sie arbeiten mit einem Foto. Sie können das Bild zwar automatisch in SVG konvertieren, aber die Vektorisierung von Fotos macht wenig Sinn, da vergrößerte Versionen in der Regel nicht gut aussehen.
Hintergrund
Eine kurze Geschichte der Displaydichte
In den Anfangszeiten hatten Computerdisplays eine Pixeldichte von 72 oder 96 dpi (Dots per Inch).
Die Pixeldichte von Displays wurde nach und nach verbessert, was vor allem auf den mobilen Einsatz zurückzuführen ist, bei dem Nutzer ihre Smartphones in der Regel näher an ihr Gesicht halten, wodurch Pixel besser sichtbar sind. 2008 waren Smartphones mit 150 dpi der neue Standard. Der Trend zu einer höheren Displaydichte setzte sich fort und die heutigen Smartphones haben Displays mit 300 dpi (von Apple als „Retina“ bezeichnet).
Der heilige Gral ist natürlich ein Display, bei dem Pixel vollständig unsichtbar sind. Beim Formfaktor von Smartphones kommt die aktuelle Generation von Retina-/HiDPI-Displays diesem Ideal möglicherweise schon sehr nahe. Aber neue Hardware- und Wearables-Klassen wie Project Glass werden wahrscheinlich weiterhin zu einer höheren Pixeldichte führen.
In der Praxis sollten Bilder mit niedriger Pixeldichte auf neuen Bildschirmen genauso aussehen wie auf alten. Im Vergleich zu den scharfen Bildern mit hoher Pixeldichte, die Nutzer gewohnt sind, wirken Bilder mit niedriger Pixeldichte jedoch irritierend und pixelig. Im Folgenden sehen Sie eine grobe Simulation, wie ein 1:1-Bild auf einem 2:1-Display aussehen würde. Im Gegensatz dazu sieht das 2-fache Bild ziemlich gut aus.


Google Pixel im Web
Als das Web entwickelt wurde, hatten 99% der Bildschirme 96 dpi (oder gaben vor, 96 dpi zu haben) und es wurden nur wenige Vorkehrungen für Abweichungen in dieser Hinsicht getroffen. Aufgrund der großen Vielfalt an Bildschirmgrößen und -dichten benötigten wir eine Standardmethode, mit der Bilder auf einer Vielzahl von Bildschirmdichten und -abmessungen gut aussehen.
In der HTML-Spezifikation wurde dieses Problem vor Kurzem durch die Definition eines Referenzpixels angegangen, mit dem Hersteller die Größe eines CSS-Pixels bestimmen.
Anhand des Referenzpixels kann ein Hersteller die Größe des physischen Pixels des Geräts relativ zum Standard- oder Idealpixel bestimmen. Dieses Verhältnis wird als Pixel-Verhältnis des Geräts bezeichnet.
Pixel-Verhältnis des Geräts berechnen
Angenommen, ein Smartphone hat ein Display mit einer physischen Pixelgröße von 180 Pixeln pro Zoll (ppi). Das Pixel-Verhältnis des Geräts wird in drei Schritten berechnet:
Vergleichen Sie den tatsächlichen Abstand, in dem das Gerät gehalten wird, mit dem Abstand für das Referenzpixel.
Gemäß der Spezifikation sind bei 28 Zoll 96 Pixel pro Zoll ideal. Da es sich jedoch um ein Smartphone handelt, halten Nutzer das Gerät näher an ihr Gesicht als einen Laptop. Angenommen, dieser Abstand beträgt 46 Zentimeter.
Multiplizieren Sie das Abstandsverhältnis mit der Standarddichte (96 ppi), um die ideale Pixeldichte für die angegebene Entfernung zu erhalten.
idealPixelDensity = (28/18) * 96 = 150 Pixel pro Zoll (ungefähr)
Das Pixel-Verhältnis des Geräts ergibt sich aus dem Verhältnis der physischen Pixeldichte zur idealen Pixeldichte.
devicePixelRatio
= 180/150 = 1,2

Wenn ein Browser also wissen muss, wie er ein Bild so skaliert, dass es der idealen oder Standardauflösung des Bildschirms entspricht, greift er auf das Pixelverhältnis des Geräts von 1,2 zurück. Das bedeutet, dass dieses Gerät für jedes ideale Pixel 1,2 physische Pixel hat. Die Formel für die Umwandlung zwischen idealen (wie in der Webspezifikation definiert) und physischen Pixeln (Punkte auf dem Bildschirm des Geräts) lautet:
physicalPixels = window.devicePixelRatio * idealPixels
Bisher haben Geräteanbieter devicePixelRatios
(DPRs) in der Regel gerundet. Für iPhones und iPads von Apple wird ein DPR von 1 und für die Retina-Modelle von Apple ein DPR von 2 erfasst. Die CSS-Spezifikation empfiehlt,
Die Pixeleinheit bezieht sich auf die ganze Anzahl der Gerätepixel, die dem Referenzpixel am besten entspricht.
Ein Grund dafür, dass runde Proportionen besser sein können, ist, dass sie zu weniger Subpixel-Artefakten führen können.
Die Realität der Gerätelandschaft ist jedoch viel vielfältiger und Android-Smartphones haben oft eine DPR von 1,5. Das Nexus 7-Tablet hat einen DPR von etwa 1,33, der durch eine ähnliche Berechnung wie oben ermittelt wurde. In Zukunft werden weitere Geräte mit variablen DPRs eingeführt. Daher sollten Sie niemals davon ausgehen, dass Ihre Kunden eine ganzzahlige DPR haben.
Übersicht über HiDPI-Bildtechniken
Es gibt viele Techniken, um das Problem zu lösen, Bilder so schnell wie möglich in der bestmöglichen Qualität zu präsentieren. Sie lassen sich grob in zwei Kategorien unterteilen:
- Optimieren einzelner Bilder und
- Optimierung der Auswahl zwischen mehreren Bildern.
Ansätze mit einem einzelnen Bild: Verwenden Sie ein Bild, aber machen Sie etwas Cleveres damit. Diese Ansätze haben den Nachteil, dass Sie zwangsläufig Abstriche bei der Leistung machen müssen, da Sie auch auf älteren Geräten mit niedrigerem DPI HiDPI-Bilder herunterladen. Hier sind einige Ansätze für den Fall mit einem einzelnen Bild:
- Stark komprimiertes HiDPI-Bild
- Super tolles Bildformat
- Progressives Bildformat
Mehrere Bilder: Verwenden Sie mehrere Bilder, aber wählen Sie auf intelligente Weise aus, welches geladen werden soll. Bei diesen Ansätzen müssen Entwickler mehrere Versionen desselben Assets erstellen und dann eine Entscheidungstrategie entwickeln. So sehen die einzelnen Optionen aus:
- JavaScript
- Serverseitige Bereitstellung
- CSS-Medienabfragen
- Integrierte Browserfunktionen (
image-set()
,<img srcset>
)
Stark komprimiertes HiDPI-Bild
Bilder machen bereits 60% der Bandbreite aus, die für den Download einer durchschnittlichen Website benötigt wird. Durch die Bereitstellung von HiDPI-Bildern für alle Clients möchten wir diese Zahl erhöhen. Wie viel größer wird es?
Ich habe einige Tests durchgeführt, bei denen 1- und 2-fache Bildfragmente mit einer JPEG-Qualität von 90, 50 und 20 generiert wurden. Hier ist das Shell-Script, das ich mit ImageMagick verwendet habe, um sie zu generieren:



Diese kleine, unwissenschaftliche Stichprobe legt nahe, dass das Komprimieren großer Bilder ein gutes Verhältnis zwischen Qualität und Größe bietet. Meiner Meinung nach sehen stark komprimierte Bilder mit doppelter Auflösung besser aus als unkomprimierte Bilder mit einfacher Auflösung.
Natürlich ist es schlechter, wenn Sie Geräten mit doppelter Auflösung Bilder mit doppelter Auflösung und geringer Qualität präsentieren, als wenn Sie Bilder mit höherer Qualität präsentieren. Der oben beschriebene Ansatz führt zu Qualitätseinbußen. Wenn Sie „Qualität: 90 Bilder“ mit „Qualität: 20 Bilder“ vergleichen, ist das Bild bei 90 Bildern weniger scharf und körniger. Diese Artefakte sind möglicherweise nicht akzeptabel, wenn Bilder hoher Qualität entscheidend sind (z. B. in einer Fotoansicht) oder für App-Entwickler, die keine Kompromisse eingehen möchten.
Der Vergleich oben wurde ausschließlich mit komprimierten JPEGs durchgeführt. Es ist wichtig zu wissen, dass es viele Kompromisse zwischen den weit verbreiteten Bildformaten (JPEG, PNG, GIF) gibt. Das bringt uns zu…
Super Bildformat
WebP ist ein ziemlich interessantes Bildformat, das sehr gut komprimiert und gleichzeitig eine hohe Bildtreue beibehält. Natürlich ist die Funktion noch nicht überall implementiert.
Eine Möglichkeit, die WebP-Unterstützung zu prüfen, ist JavaScript. Sie laden ein 1-Pixel-Bild über die Data-URI, warten, bis das Bild geladen wurde oder ein Fehlerereignis ausgelöst wurde, und prüfen dann, ob die Größe korrekt ist. Modernizr wird mit einem solchen Funktionserkennungs-Script geliefert, das über Modernizr.webp
verfügbar ist.
Besser ist es jedoch, dies direkt in CSS mit der image()-Funktion zu tun. Wenn Sie also ein WebP-Bild und einen JPEG-Fallback haben, können Sie Folgendes schreiben:
#pic {
background: image("foo.webp", "foo.jpg");
}
Dieser Ansatz birgt einige Probleme. Erstens ist image()
nicht weit verbreitet. Zweitens: Die WebP-Komprimierung ist zwar um ein Vielfaches besser als JPEG, aber es handelt sich immer noch um eine relativ geringe Verbesserung – etwa 30% kleiner als in dieser WebP-Galerie. WebP allein reicht also nicht aus, um das Problem mit hoher Auflösung zu lösen.
Progressive Bildformate
Progressive Bildformate wie JPEG 2000, Progressive JPEG, Progressive PNG und GIF haben den (etwas umstrittenen) Vorteil, dass das Bild schon angezeigt wird, bevor es vollständig geladen ist. Sie können zwar etwas mehr Speicherplatz belegen, aber es gibt widersprüchliche Beweise dafür. Jeff Atwood behauptete, dass der progressive Modus „die Größe von PNG-Bildern um etwa 20% und die von JPEG- und GIF-Bildern um etwa 10% erhöht“. Stoyan Stefanov behauptet jedoch, dass der progressive Modus bei großen Dateien in den meisten Fällen effizienter ist.
Auf den ersten Blick klingen progressive Bilder sehr vielversprechend, wenn es darum geht, Bilder in der bestmöglichen Qualität so schnell wie möglich zu liefern. Der Browser kann das Herunterladen und Decodieren eines Bildes beenden, sobald er weiß, dass zusätzliche Daten die Bildqualität nicht verbessern (d. h. alle Verbesserungen der Wiedergabequalität liegen unter einem Pixel).
Verbindungen lassen sich zwar leicht beenden, sind aber oft teuer, um sie wiederherzustellen. Bei einer Website mit vielen Bildern ist es am effizientesten, eine einzelne HTTP-Verbindung aufrechtzuerhalten und so lange wie möglich wiederzuverwenden. Wenn die Verbindung vorzeitig beendet wird, weil ein Bild ausreichend heruntergeladen wurde, muss der Browser eine neue Verbindung herstellen. Das kann in Umgebungen mit niedriger Latenz sehr langsam sein.
Eine Lösung für dieses Problem ist die Verwendung der HTTP-Bereichsanfrage, mit der Browser einen Bereich von Byte angeben können, der abgerufen werden soll. Ein intelligenter Browser könnte eine HEAD-Anfrage senden, um den Header abzurufen, ihn zu verarbeiten, zu entscheiden, wie viel des Bildes tatsächlich benötigt wird, und ihn dann abzurufen. Leider wird der HTTP-Bereich auf Webservern nur schlecht unterstützt, was diesen Ansatz unpraktisch macht.
Eine offensichtliche Einschränkung dieses Ansatzes besteht darin, dass Sie nicht auswählen können, welches Bild geladen werden soll, sondern nur die verschiedenen Auflösungen desselben Bildes. Daher wird der Anwendungsfall Art Direction nicht abgedeckt.
Mit JavaScript festlegen, welches Bild geladen werden soll
Der erste und naheliegendste Ansatz, um zu entscheiden, welches Bild geladen werden soll, ist die Verwendung von JavaScript im Client. So können Sie alles über Ihren User-Agent herausfinden und die richtige Entscheidung treffen. Sie können das Pixelverhältnis des Geräts über window.devicePixelRatio
ermitteln, die Bildschirmbreite und -höhe abrufen und sogar über navigator.connection oder durch Auslösen einer gefälschten Anfrage ein wenig Netzwerkverbindungs-Sniffing durchführen, wie es die foresight.js-Bibliothek tut. Sobald Sie alle diese Informationen erfasst haben, können Sie entscheiden, welches Bild geladen werden soll.
Es gibt ungefähr eine Million JavaScript-Bibliotheken, die so etwas tun, und leider sticht keine davon besonders hervor.
Ein großer Nachteil dieses Ansatzes ist, dass das Laden von Bildern verzögert wird, bis der Vorschau-Parser fertig ist. Das bedeutet, dass Bilder erst nach dem Auslösen des Ereignisses pageload
heruntergeladen werden. Weitere Informationen finden Sie im Artikel von Jason Grigsby.
Festlegen, welches Bild auf dem Server geladen werden soll
Sie können die Entscheidung auf die Serverseite verschieben, indem Sie benutzerdefinierte Anfragehandler für jedes Bild schreiben, das Sie bereitstellen. Ein solcher Handler würde anhand des User-Agents (der einzigen Information, die an den Server weitergeleitet wird) nach Retina-Unterstützung suchen. Je nachdem, ob die serverseitige Logik HiDPI-Assets bereitstellen soll, wird das entsprechende Asset geladen, das gemäß einer bekannten Konvention benannt ist.
Leider enthält der User-Agent nicht unbedingt genügend Informationen, um zu entscheiden, ob ein Gerät Bilder in hoher oder niedriger Qualität erhalten soll. Außerdem gilt selbstverständlich, dass alles, was mit User-Agent zu tun hat, ein Hack ist und nach Möglichkeit vermieden werden sollte.
CSS-Medienabfragen verwenden
Da sie deklarativ sind, können Sie mit CSS-Medienabfragen Ihre Absicht formulieren und den Browser die richtige Entscheidung treffen lassen. Neben der gängigsten Verwendung von Medienabfragen, der Gerätegröße, können Sie auch devicePixelRatio
abgleichen. Die zugehörige Medienabfrage ist „device-pixel-ratio“ und hat wie erwartet minimale und maximale Varianten. Wenn Sie Bilder mit hoher Auflösung laden möchten und das Pixelverhältnis des Geräts einen Grenzwert überschreitet, haben Sie folgende Möglichkeiten:
#my-image { background: (low.png); }
@media only screen and (min-device-pixel-ratio: 1.5) {
#my-image { background: (high.png); }
}
Mit den verschiedenen Anbieterpräfixen wird es etwas komplizierter, vor allem aufgrund der Unterschiede bei der Platzierung der Präfixe „min“ und „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);
}
}
Mit diesem Ansatz können Sie die Vorteile des Vorab-Parsings wieder nutzen, die mit der JS-Lösung verloren gegangen sind. Außerdem haben Sie die Flexibilität, Ihre responsiven Wendepunkte auszuwählen (z. B. Bilder mit niedriger, mittlerer und hoher DPI), was beim serverseitigen Ansatz nicht möglich war.
Leider ist es immer noch etwas unhandlich und führt zu merkwürdig aussehendem CSS (oder erfordert eine Vorverarbeitung). Außerdem ist dieser Ansatz auf CSS-Properties beschränkt. Es gibt also keine Möglichkeit, ein <img src>
festzulegen, und alle Bilder müssen Elemente mit einem Hintergrund sein. Wenn Sie sich ausschließlich auf das Pixelverhältnis des Geräts verlassen, kann es vorkommen, dass Ihr Smartphone mit hoher Auflösung ein riesiges Bild-Asset im doppelten Umfang herunterlädt, während es mit einer EDGE-Verbindung verbunden ist. Das ist nicht besonders nutzerfreundlich.
Neue Browserfunktionen verwenden
In letzter Zeit wurde viel über die Unterstützung von Webplattformen für das Problem mit Bildern mit hoher Auflösung diskutiert. Apple hat vor Kurzem die CSS-Funktion image-set() in WebKit eingeführt. Daher wird es sowohl von Safari als auch von Chrome unterstützt. Da es sich bei image-set()
um eine CSS-Funktion handelt, wird das Problem für <img>
-Tags nicht behoben. Hier kommt @srcset ins Spiel. Dieses Attribut behebt dieses Problem, hat aber (zum Zeitpunkt der Erstellung dieses Artikels) noch keine Referenzimplementierungen. Im nächsten Abschnitt werden image-set
und srcset
genauer erläutert.
Browserfunktionen für die Unterstützung hoher Auflösungen
Welchen Ansatz Sie wählen, hängt letztendlich von Ihren spezifischen Anforderungen ab. Beachten Sie jedoch, dass alle oben genannten Ansätze Nachteile haben. Sobald image-set
und srcset jedoch weithin unterstützt werden, sind sie die geeigneten Lösungen für dieses Problem. Sehen wir uns jetzt einige Best Practices an, mit denen wir dieser idealen Zukunft so nahe wie möglich kommen.
Wie unterscheiden sich diese beiden Begriffe? image-set()
ist eine CSS-Funktion, die als Wert für die CSS-Eigenschaft „background“ verwendet werden kann. „srcset“ ist ein Attribut, das für <img>
-Elemente spezifisch ist und eine ähnliche Syntax hat.
Mit beiden Tags können Sie Bilddeklarationen angeben. Mit dem srcset-Attribut können Sie jedoch auch konfigurieren, welches Bild basierend auf der Größe des Darstellungsbereichs geladen werden soll.
Best Practices für Bildsätze
Die CSS-Funktion image-set()
ist mit dem Präfix -webkit-image-set()
verfügbar. Die Syntax ist recht einfach. Sie besteht aus einer oder mehreren kommagetrennten Bilddeklarationen, die aus einem URL-String oder einer url()
-Funktion gefolgt von der zugehörigen Auflösung bestehen. Beispiel:
background-image: -webkit-image-set(
url(icon1x.jpg) 1x,
url(icon2x.jpg) 2x
);
Dem Browser wird damit mitgeteilt, dass zwei Bilder zur Auswahl stehen. Eine davon ist für 1:1-Displays und die andere für 2:1-Displays optimiert. Der Browser wählt dann anhand verschiedener Faktoren aus, welche Version geladen werden soll. Dazu kann auch die Netzwerkgeschwindigkeit gehören, wenn der Browser intelligent genug ist (derzeit nicht implementiert).
Der Browser lädt nicht nur das richtige Bild, sondern skaliert es auch entsprechend. Mit anderen Worten: Der Browser geht davon aus, dass zwei Bilder doppelt so groß sind wie ein einzelnes Bild. Daher wird das doppelte Bild um den Faktor 2 verkleinert, damit es auf der Seite dieselbe Größe hat.
Anstatt 1x, 1,5x oder Nx anzugeben, können Sie auch eine bestimmte Pixeldichte des Geräts in dpi angeben.
Das funktioniert gut, außer in Browsern, die das Attribut image-set
nicht unterstützen. In diesen Browsern wird kein Bild angezeigt. Das ist natürlich nicht gut. Sie müssen also einen Fallback (oder eine Reihe von Fallbacks) verwenden, um dieses Problem zu beheben:
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
);
Dadurch wird das entsprechende Asset in Browsern geladen, die „image-set“ unterstützen, andernfalls wird auf das 1x-Asset zurückgegriffen. Der offensichtliche Nachteil ist, dass die Browserunterstützung für image-set()
zwar gering ist, die meisten User-Agents aber das 1x-Asset erhalten.
In dieser Demo wird die image-set()
verwendet, um das richtige Bild zu laden. Wenn diese CSS-Funktion nicht unterstützt wird, wird auf das 1x-Asset zurückgegriffen.
An dieser Stelle fragen Sie sich vielleicht, warum Sie nicht einfach eine Polyfill-Lösung (d. h. einen JavaScript-Shim) für image-set()
erstellen und damit fertig sind. Es ist jedoch ziemlich schwierig, effiziente polyfills für CSS-Funktionen zu implementieren. Eine ausführliche Erklärung dazu finden Sie in dieser Diskussion zum www-Stil.
Bild-Srcset
Hier ein Beispiel für srcset:
<img alt="my awesome image"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">
Wie Sie sehen, nimmt das srcset-Element neben den x-Deklarationen, die image-set
bereitstellt, auch die Werte „w“ und „h“ an, die der Größe des Darstellungsbereichs entsprechen. So wird versucht, die relevanteste Version zu senden. Mit dem obigen Beispiel wird „banner-phone.jpeg“ auf Geräten mit einer Ansichtsbreite von weniger als 640 Pixeln, „banner-phone-HD.jpeg“ auf Geräten mit kleinem Bildschirm und hoher Auflösung, „banner-HD.jpeg“ auf Geräten mit hoher Auflösung und einem Bildschirm mit mehr als 640 Pixeln und „banner.jpeg“ auf allen anderen Geräten ausgeliefert.
„Bildsatz“ für Bildelemente verwenden
Da das Attribut „srcset“ für img-Elemente in den meisten Browsern nicht implementiert ist, kann es verlockend sein, Ihre img-Elemente durch <div>
s mit Hintergründen zu ersetzen und den Ansatz „Image-Set“ zu verwenden. Das funktioniert, aber mit Einschränkungen. Der Nachteil dabei ist, dass das <img>
-Tag einen langfristigen semantischen Wert hat. In der Praxis ist dies vor allem aus Gründen der Barrierefreiheit und für Webcrawler wichtig.
Wenn Sie -webkit-image-set
verwenden, sollten Sie die CSS-Eigenschaft „background“ nicht verwenden. Der Nachteil dieses Ansatzes besteht darin, dass Sie die Bildgröße angeben müssen, die bei einem anderen als 1:1-Bild unbekannt ist.
Stattdessen können Sie die CSS-Eigenschaft „content“ so verwenden:
<div id="my-content-image"
style="content: -webkit-image-set(
url(icon1x.jpg) 1x,
url(icon2x.jpg) 2x);">
</div>
Dadurch wird das Bild automatisch anhand von „devicePixelRatio“ skaliert. In diesem Beispiel wird die oben beschriebene Methode mit einem zusätzlichen Fallback auf url()
für Browser veranschaulicht, die image-set
nicht unterstützen.
Polyfill für srcset
Eine praktische Funktion von srcset
ist, dass es einen natürlichen Fallback hat.
Wenn das srcset-Attribut nicht implementiert ist, verarbeiten alle Browser das src-Attribut. Da es sich nur um ein HTML-Attribut handelt, ist es auch möglich, Polyfills mit JavaScript zu erstellen.
Diese Polyfill-Funktion wird mit Unit-Tests geliefert, um sicherzustellen, dass sie möglichst nah an der Spezifikation liegt. Außerdem gibt es Prüfungen, die verhindern, dass der Polyfill Code ausführt, wenn srcset nativ implementiert ist.
Hier ist eine Demo der polyfill in Aktion.
Fazit
Es gibt keine Zauberlösung für das Problem mit Bildern mit hoher Auflösung.
Die einfachste Lösung besteht darin, Bilder vollständig zu vermeiden und stattdessen SVG und CSS zu verwenden. Das ist jedoch nicht immer realistisch, insbesondere wenn Sie hochwertige Bilder auf Ihrer Website haben.
Ansätze in JS, CSS und die Verwendung der Serverseite haben alle ihre Stärken und Schwächen. Am vielversprechendsten ist jedoch die Nutzung neuer Browserfunktionen. Auch wenn die Browserunterstützung für image-set
und srcset
noch nicht vollständig ist, gibt es bereits vernünftige Fallback-Lösungen.
Zusammenfassend sind das meine Empfehlungen:
- Verwenden Sie für Hintergrundbilder image-set mit den entsprechenden Fallbacks für Browser, die es nicht unterstützen.
- Verwenden Sie für Inhaltsbilder eine srcset-Polyfill oder image-set (siehe oben).
- Wenn Sie bereit sind, die Bildqualität zu opfern, können Sie stark komprimierte 2x-Bilder verwenden.