Responsive Webdesign ist für moderne Websites und Webanwendungen zum Standard geworden. Es sorgt für ein einheitliches Erlebnis auf einer Vielzahl von Geräten und optimiert gleichzeitig die Anzeige für jedes Gerät. Allerdings unterscheiden sich moderne Geräte nicht nur in der Bildschirmgröße, sondern auch in der Pixeldichte. Das HTML5- img-
Tag bietet eine Reihe von Funktionen, die es dem Browser ermöglichen, das am besten geeignete Asset auszuwählen, wenn der Server mehrere Varianten bereitstellt. Wenn die Website dasselbe Bild in mehreren unterschiedlichen Größen bereitstellt, kann der Webbrowser die Größe auswählen, die für seine aktuelle Umgebung am besten geeignet ist.
Mithilfe reaktionsfähiger Bilder kann der Webbrowser daher eine Darstellung erstellen, die der Absicht des Designers genau entspricht. Dies verbessert zwar das Benutzererlebnis, stellt jedoch auch eine zusätzliche Belastung für die Entwicklungs- und Betriebsteams dar, die nun neben dem Standardimage zahlreiche Image-Asset-Varianten erstellen und bereitstellen müssen.
In diesem Blogbeitrag zeigen wir, wie Sie mit dem Image‑Filter-Modul für NGINX und NGINX Plus reaktionsfähige Bilder bereitstellen, ohne unzählige Bild-Asset-Varianten erstellen und verwalten zu müssen – stattdessen können wir für jedes Bild eine einzige „Quell“-Version bereitstellen, deren Größe NGINX oder NGINX Plus im Handumdrehen anpasst. Die Informationen in diesem Beitrag gelten sowohl für NGINX Open Source als auch für NGINX Plus (mit Ausnahme der separaten Anweisungen unter Installieren des Image-Filter-Moduls ). Der Kürze halber beziehen wir uns durchgehend auf NGINX Plus.
srcset-
AttributDas wichtigste Tool zum Bereitstellen reaktionsfähiger Bilder ist das srcset-
Attribut des HTML5 -img-
Tags. Wir können es verwenden, um eine Reihe von Bild-Asset-Varianten für unterschiedliche Pixeldichten und Ansichtsfenstergrößen anzugeben. „Ansichtsfenster“ ist ein allgemeiner Begriff für den Anzeigebereich, der dem Webbrowser zur Verfügung steht, sei es in einem Fenster auf einem Desktop oder einer Vollbild-App auf einem Mobilgerät.
Im folgenden Beispiel definiert das src-
Attribut ein Standardbild für Browser, die das srcset
-Attribut nicht unterstützen, und das srcset
-Attribut benennt zwei Varianten – eine für Displays mit Standardpixeldichte ( 1x
) und eine zweite für Displays mit doppelter Pixeldichte, wie etwa Apple Retina™-Displays und einige 4K-Monitore ( 2x
).
< img src= "/images/mylogo-default.png" srcset= "/images/mylogo-density1.png 1x, /images/mylogo-density2.png 2x" >
Das folgende, etwas anspruchsvollere Beispiel definiert eine Anzahl anzuzeigender Bild-Asset-Varianten entsprechend der Breite des Ansichtsfensters. Das Größenattribut
gibt an, dass der Browser ein Bild in der Hälfte des Ansichtsfensters rendert, wenn das Ansichtsfenster breiter als 10 em
ist, und andernfalls das gesamte Ansichtsfenster verwendet. Der Browser ermittelt, wie viel Platz für das Bild verfügbar ist, und wählt die Bild-Asset-Variante aus, die am besten in den verfügbaren Platz passt. Dabei wird normalerweise auf die nächste Breite aufgerundet (Suffix „w
“) und die Größe des Bildes intern angepasst, um den Platz genau auszufüllen.
< img src= "/images/racecar-default.jpg" Größen= "(Mindestbreite: 10em) 50vw, 100vw" srcset= "/images/racecar-100px.jpg 100w, /images/racecar-225px.jpg 225w, /images/racecar-450px.jpg 450w, /images/racecar-675px.jpg 675w" >
Dieser Ansatz zur Bereitstellung reaktionsfähiger Bilder durch die Angabe einer Reihe von Bild-Asset-Varianten ist einfach zu codieren und äußerst effektiv. Allerdings stellt es eine Herausforderung dar, die Bildvarianten selbst zu erstellen und zu verwalten. Sie müssen vor der Produktion umfangreiche Bildgrößenanpassungen vornehmen und eine weitaus größere Anzahl von Dateien auf dem Server bereitstellen. Das Optimieren der Anzahl und Größe jeder Variante kann zeitaufwändig sein. Dadurch gestaltet sich die Prüfung, ob die einzelnen Bild-Asset-Varianten zugänglich sind, schwierig.
Weitere Informationen zum srcset-
Attribut und anderen Techniken für responsive Bilder finden Sie in diesem tollen Blog-Beitrag .
Das Verfahren zum Abrufen dieses Image-Filter-Moduls ist für NGINX Plus und NGINX unterschiedlich.
Das Image-Filter-Modul ist als kostenloses dynamisches Modul für NGINX Plus-Abonnenten verfügbar.
Besorgen Sie sich das Modul selbst, indem Sie es aus dem NGINX Plus-Repository installieren.
Für Ubuntu- und Debian-Systeme:
$ sudo apt-get installiere nginx-plus-module-image-filter
Für RedHat-, CentOS- und Oracle Linux-Systeme:
$ sudo yum installiere nginx-plus-module-image-filter
Aktivieren Sie das Modul, indem Sie eine load_module-
Direktive dafür in den Kontext der obersten Ebene („main“) der Konfigurationsdatei nginx.conf aufnehmen (also nicht in den HTTP-
oder Stream
-Kontexten).
Lademodulmodule/ngx_http_image_filter_module.so;
Laden Sie NGINX Plus neu, um das Image-Filter-Modul in die laufende Instanz zu laden.
$ sudo nginx -s neu laden >
Am einfachsten installieren Sie das Image-Filter-Modul, indem Sie es aus dem offiziellen NGINX-Repository beziehen. Befolgen Sie diese Anweisungen , um Ihr System für den Zugriff auf das offizielle NGINX-Repository zu konfigurieren und es dann mit dem Paketmanager Ihres Betriebssystems zu installieren.
Für Ubuntu- und Debian-Systeme:
$ sudo apt-get installiere nginx-module-image-filter
Für Red Hat-, CentOS- und Oracle Linux-Systeme:
$ sudo yum installiere nginx-module-image-filter
Befolgen Sie nach der Installation die Schritte 2 und 3 unter Installieren des Image-Filter-Moduls für NGINX Plus, um NGINX zu konfigurieren und neu zu laden.
Es ist auch möglich, das Image-Filter-Modul aus dem Quellcode zu kompilieren und es entweder als statisch kompiliertes oder dynamisches Modul zu laden. Weitere Einzelheiten finden Sie im NGINX Plus-Administratorhandbuch .
Mit dem Image-Filter-Modul können wir für jedes Bild eine einzelne „Quell“-Version erstellen und bereitstellen und die Größe von NGINX Plus im laufenden Betrieb anpassen lassen, um alle vom Browser angeforderten Größenvarianten bereitzustellen. Wir können responsive Webseiten und Bilder vollständig innerhalb der HTML-Quelle optimieren, ohne die Größe der Bilder manuell ändern und sie auf unserem Webserver bereitstellen zu müssen.
In dieser Beispiel-HTML-Datei definieren wir vier Bildvarianten für Geräte mit unterschiedlicher Pixeldichte.
< html > < head > < title > Responsive Logo title > head > < body > < h2 > Logoauswahl basierend auf Pixeldichte h2 > < img src= "/img400/mylogo.png" srcset= "/img400/mylogo.png 1x, /img800/mylogo.png 2x, /img1200/mylogo.png 3x, /img1600/mylogo.png 4x" > body > html >
Die Verzeichnisse /img400 , /img800 , /img1200 und /img1600 existieren tatsächlich nicht. Stattdessen gleicht die folgende NGINX Plus-Konfiguration Anforderungen für Assets mit dem Präfix /img ab und wandelt sie in Anforderungen zum Ändern der Bildgröße im ursprünglichen Dateinamen um (z. B. mylogo.png im vorangehenden HTML).
Server { listen 80;
root /var/www/public_html;
Standort ~ ^/img([0-9]+)(?:/(.*))?$ {
alias /var/www/source_images/$2;
Bildfilterpuffer 10M;
Bildfiltergröße ändern $1 -;
}
}
Der Serverblock
definiert, wie NGINX Plus eingehende HTTP-Anfragen verarbeitet. Die Listen-
Direktive weist NGINX Plus an, auf Port 80 zu lauschen – dem Standard für HTTP-Verkehr. Die Root
-Direktive gibt den Speicherort dieser Website auf der Festplatte an. In diesem einfachen Beispiel verwenden wir eine statische Website, die von NGINX Plus gehostet wird. NGINX Plus fungiert jedoch auch häufig als Reverse-Proxy für dynamische Inhalte oder als Anwendungskonnektor wie FastCGI. Alle diese Anwendungsfälle können das Image-Filter-Modul wie hier beschrieben nutzen, indem die Quellbilder auf dem NGINX Plus-Server bereitgestellt werden.
Der Standortblock
verwendet einen regulären Ausdruck, um Anforderungen für Assets abzugleichen, die in einem Verzeichnis gespeichert sind, das mit /img beginnt, gefolgt von einer oder mehreren Ziffern. Die Ziffern werden als Variable $1
erfasst und der folgende Dateiname wird als Variable $2
erfasst. Wir verwenden dann die Alias-
Direktive, um diese Anforderung aus dem Verzeichnis auf der Festplatte zu bedienen, das unsere Quellbilder enthält. Beachten Sie, dass sich dieses Verzeichnis nicht unter dem Stammpfad
befindet und Clients die Quellbilder daher nicht direkt anfordern können.
Da unsere Quellbilder wahrscheinlich sehr groß sind, möglicherweise Tausende von Pixeln breit, müssen wir sicherstellen, dass das Bildfiltermodul genügend Speicher zuweist, um sie zu laden und ihre Größe zu ändern. In diesem Beispiel verwenden wir die Direktive image_filter_buffer,
um Bilddateien mit einer Größe von bis zu 10 MB zu unterstützen.
Schließlich weist die Direktive image_filter
das Image-Filter-Modul an, die Größe des Quellbilds auf die Breite zu ändern, die aus dem Suffix des Verzeichnisnamens /img abgeleitet wird. Der Bindestrich (-) weist NGINX Plus an, das Seitenverhältnis des Quellbildes beizubehalten.
Die unter „Anpassen der Bildgröße an die Pixeldichte“ beschriebene Konfiguration kann je nach dem zum Anfordern des Bildes verwendeten Verzeichnisnamen jede Größenvariante eines Bildes liefern. In einer Produktionsumgebung möchten wir jedoch nicht warten, bis der Webserver die Größe der Bilder bei jeder Anforderung anpasst. Dies wirkt sich nicht positiv auf die Gesamtlatenz aus und kann außerdem zu einem erheblichen CPU-Overhead führen.
Die effektivste Lösung besteht darin, unsere skalierten Bildvarianten zwischenzuspeichern, sodass nachfolgende Anforderungen für jede Variante aus dem Cache bedient werden, ohne das Bildfiltermodul zu durchlaufen. Dies lässt sich mit der NGINX Plus-Konfiguration erreichen, indem wir einen separaten virtuellen Server definieren, der die Größenanpassung von Bildern durchführt und nur dann Proxy-Anfragen an diesen Server weiterleitet, wenn die angeforderte Bildgröße noch nicht im Cache vorhanden ist. Wir nennen dies den reaktionsfähigen Bildserver .
Wir müssen auch die Sicherheitsauswirkungen berücksichtigen, die sich ergeben, wenn beliebige Anforderungen zum Ändern der Bildgröße zugelassen werden. Die Konfiguration des Caching hilft nicht, wenn ein Angreifer schnelle Anfragen an eindeutige Bild-Asset-Varianten wie /img1001/mylogo.png , /img1002/mylogo.png , /img1003/mylogo.png usw. stellen würde. Selbst bei einem relativ geringen Anfragevolumen können solche Angriffe aufgrund übermäßiger CPU-Auslastung zu einem Denial-of-Service-Angriff (DoS) führen. Um dies zu beheben, wenden wir eine Ratenbegrenzung auf den responsiven Bildserver an, jedoch nicht auf den Frontend-Server, der die zwischengespeicherten Varianten enthält. Die folgende Konfiguration erweitert die Konfiguration zum Anpassen der Bildgröße an die Pixeldichte durch Anwenden von Caching und Ratenbegrenzung auf das Bildfiltermodul.
proxy_cache_path /var/www/imgcache levels=1 keys_zone=resized:1m max_size=256m;
server {
listen 80;
root /var/www/public_html;
location ~ ^/img([0-9]+)(?:/(.*))?$ {
proxy_pass http://127.0.0.1:9001;
proxy_cache resized;
proxy_cache_valid 180m;
}
}
limit_req_zone "1" zone=2persec:32k rate=2r/s;
server {
listen 9001;
allow 127.0.0.1;
deny all;
limit_req zone=2persec burst=10;
Standort ~ ^/img([0-9]+)(?:/(.*))?$ {
alias /var/www/source_images/$2;
image_filter_buffer 10M;
image_filter resize $1 -;
}
}
Wir beginnen mit der Definition des Speicherorts unserer zwischengespeicherten Bilder mit der Direktive „proxy_cache_path“
. Der Parameter keys_zone
definiert eine gemeinsam genutzte Speicherzone für den Cache-Index (genannt resized
) und weist 1 MB zu, was für etwa 8.000 skalierte Bilder ausreicht. Der Parameter max_size
definiert den Punkt, an dem NGINX Plus beginnt, die zuletzt angeforderten Bilder aus dem Cache zu entfernen, um Platz für neue zwischengespeicherte Elemente zu schaffen.
Die Standortdirektive
für den Front-End-Webserver (der auf Port 80 lauscht) verwendet die Direktive „proxy_pass“
, um Anfragen mit dem Präfix „/img“ an den intern gehosteten responsiven Bildserver (127.0.0.1:9001) zu senden. Die Direktive „proxy_cache“
aktiviert das Caching für diesen Speicherort, indem sie den Namen des Caches ( resized
) angibt, der zum Speichern von Antworten vom responsiven Bildserver verwendet werden soll. Die Direktive „proxy_cache_valid“
stellt sicher, dass skalierte Bilder mindestens 180 Minuten lang im Cache verbleiben (es sei denn, der Cache hat die maximale Größe
überschritten und die Bilder gehören zu den Bildern, die am längsten angefordert wurden) und dass fehlerhafte Antworten des responsiven Bildservers nicht zwischengespeichert werden.
Eine ausführliche Beschreibung des Caching finden Sie im Leitfaden zum Caching mit NGINX und NGINX Plus .
Bevor wir den responsiven Bildserver selbst definieren, geben wir mit der Direktive „limit_req_zone“
eine Ratenbegrenzung an. Die Direktive erzwingt selbst keine Ratenbegrenzung – sie definiert eine Ratenbegrenzung von zwei Anfragen pro Sekunde, die dann auf den responsiven Bildserver angewendet wird, indem die Direktive limit_req
in seinen Serverblock
aufgenommen wird (siehe nächster Absatz). Normalerweise wird eine Ratenbegrenzung mit einem Attribut der Anfrage verknüpft, in diesem Fall geben wir jedoch den statischen Schlüsselwert „1“
an, sodass die Begrenzung für alle Anforderer gilt. Wir setzen die Größe der gemeinsam genutzten Speicherzone auf den kleinstmöglichen Wert, 3 KB, da unser Schlüssel eine feste Kardinalität von eins hat.
Der Serverblock
für den Responsive Image Server lauscht auf Port 9001. Wir fügen die Anweisungen „Zulassen“
und „Verweigern“
ein, um anzugeben, dass nur der lokale Host (der Front-End-Webserver) eine Verbindung mit dem responsiven Bildserver herstellen kann. Anschließend wenden wir die zuvor definierte Ratenbegrenzung durch Einbeziehung der Direktive „limit_req“
an. Der Burst
-Parameter lässt 10 gleichzeitige Anfragen zu, bevor die Ratenbegrenzung erzwungen wird. Sobald die Ratenbegrenzung in Kraft ist, werden überzählige Anfragen verzögert, bis sie innerhalb der Begrenzung verarbeitet werden können.
Der Standortblock
ist identisch mit dem in „Anpassen der Bildgröße an die Pixeldichte“, wird jetzt jedoch nur ausgeführt, wenn sich das angeforderte Bild nicht im Cache befindet und die Ratenbegrenzung nicht überschritten wurde.
In dieser Basiskonfiguration fungiert eine einzelne NGINX Plus-Instanz sowohl als Front-End-Webserver als auch als reaktionsfähiger Bildserver. Die Bildverarbeitung kann sehr rechenintensiv sein, was möglicherweise zu extrem hohen Arbeitslasten führt und NGINX Plus anfällig für DoS-Angriffe macht. Um die Situation zu vermeiden, dass der Front-End-Webserver neue Anfragen nicht sofort annehmen kann, weil alle Arbeitsprozesse mit Anfragen zur Bildgrößenänderung beschäftigt sind, empfehlen wir, eine separate NGINX Plus-Instanz auszuführen, die ausschließlich der Bildverarbeitung gewidmet ist. Dadurch werden die Arbeitsprozesses für den Front-End-Webserver von denen isoliert, die die Bildverarbeitung durchführen. Um eine separate Instanz von NGINX Plus auf demselben Host auszuführen, geben Sie in der Befehlszeile eine andere Konfigurationsdatei an:
$ sudo nginx -c /etc/nginx/resize-server.conf
Die effektivste Möglichkeit, responsive Bilder in Aktion zu sehen, besteht darin, zu beobachten, wie ein Browser Entscheidungen darüber trifft, welche srcset-
Bildvariante verwendet werden soll, wenn sich die Größe des Ansichtsfensters ändert. Hier ist der HTML-Quellcode einer einfachen Bildergalerie. Beachten Sie, dass zu Demonstrationszwecken die Größenvarianten für jedes Bild leicht unterschiedlich sind, wodurch viele mögliche „Haltepunkte“ entstehen, an denen der Browser eine andere Variante auswählen kann.
<!DOCTYPE html>
<html>
<Kopf>
<Titel>Responsive Bildergalerie</Titel>
</Kopf>
<Körper>
<h2>Responsive Bildergalerie</h2>
<img Quelle="/img100/1-dominos.jpg" Größen="(Mindestbreite: 20em) 40vw, 100vw" srcset= "/img110/1-dominos.jpg 110w, /img210/1-dominos.jpg 210w, /img310/1-dominos.jpg 310w, /img410/1-dominos.jpg 410w, /img510/1-dominos.jpg 510w, /img610/1-dominos.jpg 610w" > < img src= "/img100/2-sign.jpg" Größen= "(Mindestbreite: 20em) 40vw, 100vw" srcset= "/img120/2-sign.jpg 120w, /img220/2-sign.jpg 220w, /img330/2-sign.jpg 330w, /img420/2-sign.jpg 420w, /img520/2-sign.jpg 520w, /img620/2-sign.jpg 620w" > < img src= "/img100/3-thruppence.jpg" Größen= "(Mindestbreite: 20em) 40vw, 100vw" srcset= "/img130/3-thruppence.jpg 130w, /img230/3-thruppence.jpg 230w, /img330/3-thruppence.jpg 330w, /img440/3-thruppence.jpg 440w, /img550/3-thruppence.jpg 550w, /img660/3-thruppence.jpg 660w" > < img src= "/img100/4-aces.jpg" Größen= "(Mindestbreite: 20em) 40vw, 100vw" srcset= "/img140/4-aces.jpg 140w, /img240/4-aces.jpg 240w, /img340/4-aces.jpg 340w, /img440/4-aces.jpg 440w, /img540/4-aces.jpg 540w, /img640/4-aces.jpg 640w" > body > html >
Die folgenden Screenshots zeigen den Inhalt dieser Webseite in einem Chrome-Browser mit dem auf der Registerkarte „Netzwerk“ geöffneten Inspector . In der Spalte „Name“ wird der Pfad der jeweiligen vom Server angeforderten Bildvariante angezeigt. So können wir die gewählte Größe sehen, ohne die Protokolle auf dem Webserver prüfen zu müssen.
Beim schmalen Ansichtsfenster in Abbildung 2 hat der Browser Bilder mit einer Breite zwischen 220 und 310 Pixeln ausgewählt (die numerischen Suffixe der /img -Verzeichnisnamen in der Spalte „Name“ liegen zwischen diesen Werten).
Wenn wir das Browserfenster in Abbildung 3 erweitern, wählt der Browser Bilder mit einer Breite zwischen 440 und 540 Pixeln aus (die letzten vier aufgelisteten Bilder). Der Wert für diese Bilder in der Spalte „Initiator“ ist „Sonstiges“ .
Mit NGINX Plus und dem Image‑Filter-Modul können wir die optimale Bildgröße für die aktuellen Browserbedingungen liefern. Und das ohne Größenanpassung der Bilder vor der Produktion, Stapelverarbeitung oder die Verwaltung von Hunderten von Bild-Asset-Varianten auf der Festplatte. Dies ist nur eine weitere Möglichkeit, wie NGINX Plus Ihnen dabei hilft, eine fehlerfreie Anwendungsbereitstellung zu erreichen.
Probieren Sie responsive Bilder mit NGINX Plus selbst aus – starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen .
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."