Anpassung an Nutzer mit Client Hints

Websites zu entwickeln, die überall schnell geladen werden, kann eine knifflige Angelegenheit sein. Die Vielzahl der Gerätefunktionen und die Qualität der Netzwerke, mit denen sie verbunden sind, können diese Aufgabe unüberwindbar erscheinen lassen. Wir können zwar Browserfunktionen nutzen, um die Ladeleistung zu verbessern, aber woher wissen wir, was das Gerät des Nutzers leisten kann oder wie gut seine Netzwerkverbindung ist? Die Lösung sind Client Hints.

Client Hints sind eine Reihe von HTTP-Anfrageheadern, die uns Einblick in diese Aspekte des Nutzergeräts und des Netzwerks geben, mit dem es verbunden ist. Wenn wir diese Informationen serverseitig nutzen, können wir die Art der Bereitstellung von Inhalten je nach Gerät und/oder Netzwerkbedingungen ändern. So können wir inklusivere User Experiences schaffen.

Es geht um die Inhaltsaushandlung

Client Hints sind eine weitere Methode der Inhaltsaushandlung, bei der Inhaltsantworten basierend auf Browser-Anfrageheadern geändert werden.

Ein Beispiel für die Content-Negotiation ist der Anfrageheader Accept. Er beschreibt, welche Inhaltstypen der Browser versteht, die der Server zum Aushandeln der Antwort verwenden kann. Bei Bildanfragen sieht der Inhalt des Accept-Headers von Chrome so aus:

Accept: image/webp,image/apng,image/*,*/*;q=0.8

Alle Browser unterstützen Bildformate wie JPEG, PNG und GIF. In diesem Fall gibt „Accept“ an, dass der Browser auch WebP und APNG unterstützt. Anhand dieser Informationen können wir die besten Bildtypen für jeden Browser aushandeln:

<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;

// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">

Wie Accept sind Client Hints eine weitere Möglichkeit, Inhalte auszuhandeln, allerdings im Kontext von Gerätefunktionen und Netzwerkbedingungen. Mit Client Hints können wir serverseitige Leistungsentscheidungen auf Grundlage der individuellen Nutzererfahrung treffen, z. B. ob nicht kritische Ressourcen für Nutzer mit schlechten Netzwerkbedingungen bereitgestellt werden sollen. In diesem Leitfaden werden alle verfügbaren Hinweise und einige Möglichkeiten beschrieben, wie du sie verwenden kannst, um die Inhaltsübermittlung für Nutzer zu optimieren.

Aktivieren

Im Gegensatz zum Accept-Header werden Client Hints nicht einfach so angezeigt (mit Ausnahme von Save-Data, worauf wir später noch eingehen werden). Damit die Anfrageheader möglichst kurz bleiben, müsst ihr die Client Hints, die ihr erhalten möchtet, explizit aktivieren. Dazu sendet ihr einen Accept-CH-Header, wenn ein Nutzer eine Ressource anfordert:

Accept-CH: Viewport-Width, Downlink

Der Wert für Accept-CH ist eine durch Kommas getrennte Liste der angeforderten Hinweise, die die Website verwendet, um die Ergebnisse für nachfolgende Ressourcenanfragen zu ermitteln. Wenn der Client diesen Header liest, wird ihm mitgeteilt: „Diese Website möchte die Client Hints Viewport-Width und Downlink.“ Die genauen Hinweise sind hier nicht wichtig. Dazu kommen wir gleich.

Sie können diese Opt-in-Header in jeder Backend-Sprache festlegen. Beispielsweise kann die header-Funktion von PHP verwendet werden. Sie können diese Opt-in-Header sogar mit dem Attribut http-equiv in einem <meta>-Tag festlegen:

<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />

Alle Client Hints!

Client Hints beschreiben eines von zwei Dingen: das Gerät, das Ihre Nutzer verwenden, und das Netzwerk, über das sie auf Ihre Website zugreifen. Sehen wir uns kurz alle verfügbaren Hinweise an.

Gerätehinweise

Einige Client-Hinweise beschreiben Merkmale des Geräts des Nutzers, in der Regel Bildschirmmerkmale. Einige davon können Ihnen helfen, die optimale Medienressource für den Bildschirm eines bestimmten Nutzers auszuwählen, aber nicht alle sind unbedingt medienorientiert.

Bevor wir uns diese Liste ansehen, ist es hilfreich, einige wichtige Begriffe zu kennen, die zur Beschreibung von Bildschirmen und Medienauflösungen verwendet werden:

Intrinsische Größe: die tatsächlichen Abmessungen einer Medienressource. Wenn Sie beispielsweise ein Bild in Photoshop öffnen, beschreiben die im Dialogfeld für die Bildgröße angezeigten Abmessungen die intrinsische Größe.

Dichtekorrigierte intrinsische Größe: Die Abmessungen einer Medienressource nach der Korrektur der Pixeldichte. Sie entspricht der intrinsischen Größe des Bildes geteilt durch das Gerätepixelverhältnis. Nehmen wir zum Beispiel dieses Markup:

<img
  src="whats-up-1x.png"
  srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
  alt="I'm that image you wanted."
/>

Angenommen, die intrinsische Größe des Bildes 1x beträgt in diesem Fall 320 × 240 und die intrinsische Größe des Bildes 2x beträgt 640 × 480. Wenn dieses Markup von einem Client geparst wird, der auf einem Gerät mit einem Gerätepixelverhältnis von 2 (z.B. einem Retina-Bildschirm) installiert ist, wird das Bild 2x angefordert. Die dichtekorrigierte intrinsische Größe des Bildes 2x beträgt 320 × 240, da 640 × 480 geteilt durch 2 gleich 320 × 240 ist.

Extrinsische Größe: Die Größe einer Medienressource, nachdem CSS und andere Layoutfaktoren (z. B. die Attribute width und height) darauf angewendet wurden. Angenommen, Sie haben ein <img>-Element, das ein Bild mit einer dichte-korrigierten intrinsischen Größe von 320 × 240 lädt, aber auch die CSS-Eigenschaften width und height mit den Werten 256px bzw. 192px darauf angewendet werden. In diesem Beispiel beträgt die extrinsische Größe des <img>-Elements 256 × 192.

Eine Abbildung, die den Unterschied zwischen intrinsischer und extrinsischer Größe zeigt. Ein Feld mit der Größe 320 × 240 Pixel wird mit dem Label INTRINSIC SIZE angezeigt. Darin befindet sich ein kleineres Feld mit einer Größe von 256 × 192 Pixeln, das ein HTML-img-Element mit angewendetem CSS darstellt. Dieses Feld ist mit EXTRINSIC SIZE gekennzeichnet. Rechts befindet sich ein Feld mit CSS, das auf das Element angewendet wird und das Layout des img-Elements so ändert, dass sich seine extrinsische Größe von seiner intrinsischen Größe unterscheidet.
Abbildung 1: Eine Abbildung der intrinsischen im Vergleich zur extrinsischen Größe. Ein Bild erhält seine extrinsische Größe, nachdem Layoutfaktoren darauf angewendet wurden. In diesem Fall werden durch die Anwendung der CSS-Regeln width: 256px; und height: 192px; ein Bild mit der intrinsischen Größe 320 × 240 in ein Bild mit der extrinsischen Größe 256 × 192 umgewandelt.

Nachdem wir uns mit der Terminologie vertraut gemacht haben, sehen wir uns nun die Liste der gerätespezifischen Client Hints an, die Ihnen zur Verfügung stehen.

Viewport-Width

Viewport-Width ist die Breite des Darstellungsbereichs des Nutzers in CSS-Pixeln:

Viewport-Width: 320

Dieser Hinweis kann mit anderen bildschirmspezifischen Hinweisen verwendet werden, um verschiedene Versionen (z.B. Ausschnitte) eines Bildes bereitzustellen, die für bestimmte Bildschirmgrößen optimal sind (z.B. Art Direction), oder um Ressourcen wegzulassen, die für die aktuelle Bildschirmbreite nicht erforderlich sind.

DPR

DPR, kurz für „Device Pixel Ratio“ (Gerätepixelverhältnis), gibt das Verhältnis von physischen Pixeln zu CSS-Pixeln auf dem Bildschirm des Nutzers an:

DPR: 2

Dieser Hinweis ist nützlich, wenn Bildquellen ausgewählt werden, die der Pixeldichte eines Bildschirms entsprechen (wie x-Deskriptoren im srcset-Attribut).

Breite

Der Hinweis Width wird bei Anfragen für Bildressourcen angezeigt, die von <img>- oder <source>-Tags mit dem Attribut sizes ausgelöst werden. sizes teilt dem Browser mit, wie groß die extrinsische Größe der Ressource sein wird. Width verwendet diese extrinsische Größe, um ein Bild mit einer intrinsischen Größe anzufordern, die für das aktuelle Layout optimal ist.

Angenommen, ein Nutzer fordert eine Seite mit einem 320 CSS-Pixel breiten Bildschirm mit einem DPR von 2 an. Das Gerät lädt ein Dokument mit einem <img>-Element, das einen sizes-Attributwert von 85vw enthält (d.h. 85 % der Breite des Darstellungsbereichs für alle Bildschirmgrößen). Wenn der Hinweis Width aktiviert wurde, sendet der Client diesen Hinweis Width zusammen mit der Anfrage für die src der <img> an den Server:

Width: 544

In diesem Fall gibt der Client dem Server einen Hinweis, dass eine optimale intrinsische Breite für das angeforderte Bild 85 % der Breite des Darstellungsbereichs (272 Pixel) multipliziert mit dem DPR des Bildschirms (2) wäre, was 544 Pixel entspricht.

Dieser Hinweis ist besonders nützlich, da er nicht nur die dichte-korrigierte Breite des Bildschirms berücksichtigt, sondern diese wichtige Information auch mit der extrinsischen Größe des Bildes im Layout abgleicht. So können Server Bildantworten aushandeln, die sowohl für den Bildschirm als auch für das Layout optimal sind.

Content-DPR

Du weißt bereits, dass Bildschirme ein Pixel-Verhältnis haben. Ressourcen haben aber auch eigene Pixel-Verhältnisse. In den einfachsten Anwendungsfällen für die Ressourcenauswahl können die Pixelverhältnisse zwischen Geräten und Ressourcen gleich sein. Aber! Wenn sowohl der DPR- als auch der Width-Header verwendet werden, kann die extrinsische Größe einer Ressource zu Szenarien führen, in denen sich die beiden unterscheiden. Hier kommt der Hinweis Content-DPR ins Spiel.

Im Gegensatz zu anderen Client Hints ist Content-DPR kein Anfrageheader, der von Servern verwendet wird, sondern ein Antwortheader, den Server senden müssen, wenn die Hinweise DPR und Width zur Auswahl einer Ressource verwendet werden. Der Wert von Content-DPR sollte das Ergebnis dieser Gleichung sein:

Content-DPR = [Größe der ausgewählten Bildressource] / ([Width] / [DPR])

Wenn ein Content-DPR-Anfrageheader gesendet wird, weiß der Browser, wie das angegebene Bild für das Gerätepixelverhältnis des Bildschirms und das Layout skaliert werden muss. Ohne dieses Attribut werden Bilder möglicherweise nicht richtig skaliert.

Device-Memory

Device-Memory ist technisch gesehen Teil der Device Memory API und gibt die ungefähre Menge an Arbeitsspeicher des aktuellen Geräts in GiB an:

Device-Memory: 2

Ein möglicher Anwendungsfall für diesen Hinweis wäre die Reduzierung der Menge an JavaScript, die an Browser auf Geräten mit begrenztem Arbeitsspeicher gesendet wird, da JavaScript der ressourcenintensivste Inhaltstyp ist, den Browser normalerweise laden. Oder Sie senden Bilder mit niedrigerem DPR, da für die Decodierung weniger Arbeitsspeicher benötigt wird.

Netzwerkhinweise

Die Network Information API bietet eine weitere Kategorie von Client Hints, die die Leistung der Netzwerkverbindung des Nutzers beschreiben. Meiner Meinung nach sind das die nützlichsten Hinweise. Mit ihnen können wir die Nutzererfahrung anpassen, indem wir die Bereitstellung von Ressourcen für Clients mit langsamen Verbindungen ändern.

RTT

Der Hinweis RTT gibt die ungefähre Umlaufzeit in Millisekunden auf der Anwendungsebene an. Der Hinweis RTT umfasst im Gegensatz zur RTT der Transportschicht die Serververarbeitungszeit.

RTT: 125

Dieser Hinweis ist nützlich, da die Latenz eine wichtige Rolle für die Ladeleistung spielt. Mit dem Hinweis RTT können wir Entscheidungen auf Grundlage der Netzwerkreaktionsfähigkeit treffen, was die Bereitstellung einer gesamten Website beschleunigen kann (z.B. durch das Auslassen einiger Anfragen).

Die Latenz ist zwar wichtig für die Ladeleistung, aber auch die Bandbreite hat einen Einfluss. Der Hinweis Downlink, ausgedrückt in Megabit pro Sekunde (Mbit/s), gibt die ungefähre Downstream-Geschwindigkeit der Verbindung des Nutzers an:

Downlink: 2.5

In Verbindung mit RTT kann Downlink nützlich sein, um die Bereitstellung von Inhalten für Nutzer je nach Qualität der Netzwerkverbindung zu ändern.

ECT

Der Hinweis ECT steht für Effective Connection Type (Effektiver Verbindungstyp). Der Wert ist einer der Verbindungstypen in einer Aufzählungsliste, die jeweils eine Verbindung innerhalb bestimmter Bereiche von RTT- und Downlink-Werten beschreiben.

Dieser Header gibt nicht an, um welchen Verbindungstyp es sich tatsächlich handelt. Er gibt beispielsweise nicht an, ob es sich bei Ihrem Gateway um einen Mobilfunkmast oder einen WLAN-Zugangspunkt handelt. Stattdessen werden die Latenz und Bandbreite der aktuellen Verbindung analysiert und es wird ermittelt, welchem Netzwerkprofil sie am meisten ähnelt. Wenn Sie beispielsweise über WLAN eine Verbindung zu einem langsamen Netzwerk herstellen, wird ECT möglicherweise mit dem Wert 2g gefüllt, was der nächstgelegenen Annäherung an die effektive Verbindung entspricht:

ECT: 2g

Gültige Werte für ECT sind 4g, 3g, 2g und slow-2g. Dieser Hinweis kann als Ausgangspunkt für die Bewertung der Verbindungsqualität verwendet und anschließend mit den Hinweisen RTT und Downlink verfeinert werden.

Save-Data

Save-Data ist weniger ein Hinweis, der die Netzwerkbedingungen beschreibt, sondern eher eine Nutzereinstellung, die angibt, dass Seiten weniger Daten senden sollen.

Ich klassifiziere Save-Data lieber als Netzwerkhinweis, da viele der Dinge, die Sie damit tun würden, anderen Netzwerkhinweisen ähneln. Nutzer aktivieren die Funktion möglicherweise auch in Umgebungen mit hoher Latenz oder geringer Bandbreite. Dieser Hinweis sieht, wenn vorhanden, immer so aus:

Save-Data: on

Wir bei Google haben darüber gesprochen, was Sie mit Save-Data tun können. Die Auswirkungen auf die Leistung können erheblich sein. Das ist ein Signal, dass Nutzer Sie buchstäblich darum bitten, ihnen weniger zu senden. Wenn Sie auf dieses Signal hören und entsprechend handeln, werden die Nutzer es zu schätzen wissen.

Alles miteinander verbinden

Was Sie mit Client Hints tun, hängt von Ihnen ab. Da sie so viele Informationen bieten, haben Sie viele Möglichkeiten. Sehen wir uns an, was Client Hints für Sconnie Timber, ein fiktives Holzunternehmen im ländlichen oberen Mittleren Westen, tun können. Wie so oft in abgelegenen Gebieten können Netzwerkverbindungen instabil sein. Hier kann eine Technologie wie Client Hints für Nutzer wirklich einen Unterschied machen.

Responsive Bilder

Alle Anwendungsfälle für responsive Bilder, mit Ausnahme der einfachsten, können kompliziert werden. Was ist, wenn du mehrere Varianten desselben Bildes für unterschiedliche Bildschirmgrößen und unterschiedliche Formate hast? Dieses Markup wird sehr schnell sehr kompliziert. Es ist leicht, Fehler zu machen, und wichtige Konzepte (wie sizes) können leicht vergessen oder missverstanden werden.

<picture> und srcset sind zweifellos großartige Tools, aber die Entwicklung und Wartung für komplexe Anwendungsfälle kann zeitaufwendig sein. Wir können die Markup-Generierung automatisieren, aber das ist auch schwierig, weil die von <picture> und srcset bereitgestellten Funktionen so komplex sind, dass ihre Automatisierung so erfolgen muss, dass die von ihnen gebotene Flexibilität erhalten bleibt.

Client Hints können dies vereinfachen. Die Aushandlung von Bildantworten mit Client Hints könnte etwa so aussehen:

  1. Wenn es für Ihren Workflow relevant ist, wählen Sie zuerst eine Bildbearbeitung (z.B. Art-Directed-Bilder) aus, indem Sie den Hinweis Viewport-Width beachten.
  2. Wähle eine Bildauflösung aus, indem du die Hinweise Width und DPR prüfst und eine Quelle auswählst, die zur Layoutgröße und Bildschirmdichte des Bildes passt (ähnlich wie die Deskriptoren x und w in srcset funktionieren).
  3. Wählen Sie das optimale Dateiformat aus, das vom Browser unterstützt wird. Accept hilft uns dabei in den meisten Browsern.

Für meinen fiktiven Kunden, ein Holzunternehmen, habe ich eine einfache Routine zur Auswahl responsiver Bilder in PHP entwickelt, die Client Hints verwendet. Das bedeutet, dass anstelle dieses Markups an alle Nutzer:

<picture>
  <source
    srcset="
      company-photo-256w.webp   256w,
      company-photo-512w.webp   512w,
      company-photo-768w.webp   768w,
      company-photo-1024w.webp 1024w,
      company-photo-1280w.webp 1280w
    "
    type="image/webp"
  />
  <img
    srcset="
      company-photo-256w.jpg   256w,
      company-photo-512w.jpg   512w,
      company-photo-768w.jpg   768w,
      company-photo-1024w.jpg 1024w,
      company-photo-1280w.jpg 1280w
    "
    src="company-photo-256w.jpg"
    sizes="(min-width: 560px) 251px, 88.43vw"
    alt="The Sconnie Timber Staff!"
  />
</picture>

Ich konnte die Liste basierend auf der Unterstützung durch die einzelnen Browser auf Folgendes reduzieren:

<img
  src="/image/sizes:true/company-photo.jpg"
  sizes="(min-width: 560px) 251px, 88.43vw"
  alt="SAY CHEESY PICKLES."
/>

In diesem Beispiel ist die /image-URL ein PHP-Skript, gefolgt von Parametern, die von mod_rewrite umgeschrieben wurden. Es verwendet einen Bilddateinamen und zusätzliche Parameter, damit ein Back-End-Skript das beste Bild für die jeweiligen Bedingungen auswählen kann.

Ich ahne, dass Ihre erste Frage lautet: „Aber ist das nicht nur eine Neuimplementierung von <picture> und srcset im Backend?“.

In gewisser Weise ja, aber mit einem wichtigen Unterschied: Wenn eine Anwendung Client Hints verwendet, um Medienantworten zu erstellen, ist der Großteil der Arbeit (wenn nicht sogar die gesamte Arbeit) viel einfacher zu automatisieren. Dies kann auch einen Dienst (z. B. ein CDN) umfassen, der dies für Sie erledigt. Bei HTML-Lösungen muss dagegen für jeden Anwendungsfall ein neues Markup geschrieben werden. Natürlich könnt ihr die Markup-Generierung automatisieren. Wenn sich jedoch Ihr Design oder Ihre Anforderungen ändern, müssen Sie Ihre Automatisierungsstrategie in Zukunft wahrscheinlich überarbeiten.

Mit Client Hints können Sie mit einem verlustfreien, hochauflösenden Bild beginnen, dessen Größe dann dynamisch angepasst werden kann, um für jede Kombination aus Bildschirm und Layout optimal zu sein. Im Gegensatz zu srcset, bei dem Sie eine feste Liste möglicher Bildkandidaten angeben müssen, aus denen der Browser auswählen kann, ist dieser Ansatz flexibler. Während srcset Sie dazu zwingt, Browsern eine grobe Auswahl an Varianten anzubieten, z. B. 256w, 512w, 768w und 1024w, kann eine auf Client Hints basierende Lösung alle Breiten ohne riesige Mengen an Markup bedienen.

Natürlich müssen Sie die Logik für die Bildauswahl nicht selbst schreiben. Cloudinary verwendet Client Hints, um Bildantworten zu erstellen, wenn Sie den Parameter w_auto verwenden. Dabei wurde festgestellt, dass Nutzer im Median 42 % weniger Byte heruntergeladen haben, wenn sie Browser verwendet haben, die Client Hints unterstützen.

Aber Vorsicht! In der Desktopversion von Chrome 67 wurde die Unterstützung für ursprungsübergreifende Client Hints entfernt. Glücklicherweise wirken sich diese Einschränkungen nicht auf mobile Versionen von Chrome aus und werden für alle Plattformen aufgehoben, sobald die Arbeit an der Feature Policy abgeschlossen ist.

Hilfe für Nutzer mit langsamen Netzwerken

Adaptive Leistung bedeutet, dass wir die Bereitstellung von Ressourcen basierend auf den Informationen anpassen können, die uns Client Hints zur Verfügung stellen, insbesondere Informationen zum aktuellen Status der Netzwerkverbindung des Nutzers.

Bei der Website von Sconnie Timber ergreifen wir Maßnahmen, um die Last bei langsamen Netzwerken zu verringern. Dazu werden die Header Save-Data, ECT, RTT und Downlink in unserem Back-End-Code untersucht. Anschließend wird ein Wert für die Netzwerkqualität generiert, anhand dessen wir feststellen können, ob wir eingreifen sollten, um die Nutzerfreundlichkeit zu verbessern. Dieser Netzwerk-Score liegt zwischen 0 und 1, wobei 0 die schlechteste und 1 die beste Netzwerkqualität ist.

Zuerst prüfen wir, ob Save-Data vorhanden ist. In diesem Fall wird der Wert auf 0 gesetzt, da wir davon ausgehen, dass der Nutzer möchte, dass wir alles tun, um die Nutzung einfacher und schneller zu machen.

Wenn Save-Data nicht vorhanden ist, werden die Werte der Hinweise ECT, RTT und Downlink gewichtet, um einen Wert zu berechnen, der die Qualität der Netzwerkverbindung beschreibt. Der Quellcode für die Generierung des Netzwerk-Scores ist auf GitHub verfügbar. Fazit: Wenn wir die netzwerkbezogenen Hinweise in irgendeiner Form verwenden, können wir die Nutzerfreundlichkeit für Nutzer in langsamen Netzwerken verbessern.

Vergleich einer Website, die keine Client Hints verwendet, um sich an eine langsame Netzwerkverbindung anzupassen (links), und derselben Website, die dies tut (rechts).
Abbildung 2: Eine „Über uns“-Seite für die Website eines lokalen Unternehmens. Die Baseline-Version enthält Webschriftarten, JavaScript für ein Karussell und ein Akkordeon sowie Inhaltsbilder. All diese Dinge können wir weglassen, wenn die Netzwerkbedingungen zu langsam sind, um sie schnell zu laden.

Wenn Websites sich an die Informationen anpassen, die Client Hints liefern, müssen wir keinen „Alles oder nichts“-Ansatz verfolgen. Wir können intelligent entscheiden, welche Ressourcen gesendet werden sollen. Wir können die Logik für die Auswahl responsiver Bilder so ändern, dass bei schlechter Netzwerkqualität Bilder mit geringerer Qualität für ein bestimmtes Display gesendet werden, um die Ladeleistung zu verbessern.

In diesem Beispiel sehen wir, wie sich Client Hints auf die Leistung von Websites in langsameren Netzwerken auswirken. Unten sehen Sie ein WebPagetest-Wasserfalldiagramm einer Website in einem langsamen Netzwerk, die sich nicht an Client Hints anpasst:

Ein WebPagetest-Wasserfalldiagramm der Sconnie Timber-Website, auf der alle Ressourcen über eine langsame Netzwerkverbindung geladen werden.
Abbildung 3. Eine ressourcenintensive Website, die Bilder, Skripts und Schriftarten über eine langsame Verbindung lädt.

Und jetzt ein Wasserfalldiagramm für dieselbe Website mit derselben langsamen Verbindung, aber dieses Mal werden Client Hints verwendet, um nicht kritische Seitenressourcen zu eliminieren:

Ein WebPagetest-Wasserfalldiagramm der Sconnie Timber-Website, auf der Client Hints verwendet werden, um zu entscheiden, ob nicht kritische Ressourcen bei einer langsamen Netzwerkverbindung geladen werden sollen.
Abbildung 4. Dieselbe Website mit derselben Verbindung, nur dass die „Nice-to-have“-Ressourcen zugunsten eines schnelleren Ladens ausgeschlossen werden.

Durch Client Hints wurde die Seitenladezeit von über 45 Sekunden auf weniger als ein Zehntel dieser Zeit reduziert. Die Vorteile von Client Hints in diesem Szenario können nicht genug betont werden und können für Nutzer, die wichtige Informationen über langsame Netzwerke suchen, ein großer Vorteil sein.

Außerdem ist es möglich, Client Hints zu verwenden, ohne dass die Nutzererfahrung in Browsern, die sie nicht unterstützen, beeinträchtigt wird. Wenn wir beispielsweise die Ressourcenbereitstellung mithilfe des Werts des ECT-Hinweises anpassen möchten, aber für nicht unterstützte Browser weiterhin die vollständige Website bereitstellen möchten, können wir einen Standardwert als Fallback festlegen:

// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";

Hier steht "4g" für die Netzwerkverbindung mit der höchsten Qualität, die im Header ECT beschrieben wird. Wenn wir $ect mit "4g" initialisieren, sind Browser, die keine Client Hints unterstützen, nicht betroffen. Opt-in FTW!

Achte auf die Caches!

Wenn Sie eine Antwort basierend auf einem HTTP-Header ändern, müssen Sie berücksichtigen, wie Caches zukünftige Abrufe für diese Ressource verarbeiten. Der Header Vary ist hier unverzichtbar, da er Cache-Einträge dem Wert der Anfrageheader zuordnet, die ihm bereitgestellt werden. Einfach ausgedrückt: Wenn Sie eine Antwort basierend auf einem bestimmten HTTP-Anfrageheader ändern, sollten Sie diesen Header fast immer in Vary einfügen, z. B. so:

Vary: DPR, Width

Es gibt jedoch einen großen Vorbehalt: Sie sollten niemals im Cache speicherbare Antworten mit einem sich häufig ändernden Header (z. B. Cookie) Vary, da diese Ressourcen dann praktisch nicht mehr im Cache gespeichert werden können. Daher sollten Sie Vary-Header für Client-Hinweise wie RTT oder Downlink vermeiden, da diese Verbindungsfaktoren sich häufig ändern können. Wenn Sie Antworten für diese Header ändern möchten, sollten Sie nur den Header ECT als Schlüssel verwenden, um Cache-Fehler zu minimieren.

Das gilt natürlich nur, wenn Sie überhaupt eine Antwort im Cache speichern. HTML-Assets mit dynamischen Inhalten sollten beispielsweise nicht im Cache gespeichert werden, da dies die Nutzerfreundlichkeit bei wiederholten Besuchen beeinträchtigen kann. In solchen Fällen können Sie die Antworten nach eigenem Ermessen ändern und müssen sich nicht an Vary halten.

Client Hints in Service Workern

Die Content Negotiation ist nicht mehr nur für Server gedacht. Da Service Worker als Proxys zwischen Clients und Servern fungieren, können Sie steuern, wie Ressourcen über JavaScript bereitgestellt werden. Dazu gehören auch Client Hints. Im Service Worker-Ereignis fetch können Sie die Methode request.headers.get des event-Objekts verwenden, um die Anfrageheader einer Ressource so zu lesen:

self.addEventListener('fetch', (event) => {
  let dpr = event.request.headers.get('DPR');
  let viewportWidth = event.request.headers.get('Viewport-Width');
  let width = event.request.headers.get('Width');

  event.respondWith(
    (async function () {
      // Do what you will with these hints!
    })(),
  );
});

Alle Client Hints-Header, die Sie aktivieren, können auf diese Weise gelesen werden. Das ist jedoch nicht die einzige Möglichkeit, an diese Informationen zu gelangen. Netzwerkspezifische Hinweise können in den folgenden äquivalenten JavaScript-Eigenschaften im navigator-Objekt gelesen werden:

Client Hint JS-Äquivalent
`ECT` `navigator.connection.effectiveType`
`RTT` `navigator.connection.rtt`
`Save-Data` `navigator.connection.saveData`
`Downlink` `navigator.connection.downlink`
`Device-Memory` `navigator.deviceMemory`
Imagemin-Plug-ins für Dateitypen.

Da diese APIs nicht überall verfügbar sind, müssen Sie die Verfügbarkeit der Funktion mit dem in-Operator prüfen:

if ('connection' in navigator) {
  // Work with netinfo API properties in JavaScript!
}

Hier können Sie eine ähnliche Logik wie auf dem Server verwenden, mit dem Unterschied, dass Sie keinen Server benötigen, um Inhalte mit Client Hints auszuhandeln. Service Worker allein können die Nutzung schneller und zuverlässiger machen, da sie Inhalte auch dann bereitstellen können, wenn der Nutzer offline ist.

Zusammenfassung

Mit Client Hints können wir die Nutzerfreundlichkeit auf vollständig progressive Weise verbessern. Wir können Medien basierend auf den Gerätefunktionen des Nutzers bereitstellen, sodass die Bereitstellung responsiver Bilder einfacher ist als die Verwendung von <picture> und srcset, insbesondere bei komplexen Anwendungsfällen. So können wir nicht nur Zeit und Aufwand bei der Entwicklung reduzieren, sondern auch Ressourcen – insbesondere Bilder – so optimieren, dass sie auf den Bildschirmen der Nutzer besser dargestellt werden, als es mit und srcset möglich ist.

Vielleicht noch wichtiger ist, dass wir schlechte Netzwerkverbindungen erkennen und die Lücke für Nutzer schließen können, indem wir ändern, was wir senden und wie wir es senden. Das kann viel dazu beitragen, dass Websites für Nutzer in instabilen Netzwerken leichter zugänglich sind. In Kombination mit Service Workern können wir unglaublich schnelle Websites erstellen, die offline verfügbar sind.

Client Hints sind zwar nur in Chrome und Chromium-basierten Browsern verfügbar, können aber so verwendet werden, dass Browser, die sie nicht unterstützen, nicht beeinträchtigt werden. Mit Client Hints können Sie wirklich inklusive und anpassbare Oberflächen erstellen, die die Gerätefunktionen jedes Nutzers und die Netzwerke, mit denen er sich verbindet, berücksichtigen. Hoffentlich erkennen andere Browseranbieter den Wert und zeigen Interesse an der Implementierung.

Ressourcen

Vielen Dank an Ilya Grigorik, Eric Portis, Jeff Posnick, Yoav Weiss und Estelle Weyl für ihr wertvolles Feedback und ihre Bearbeitungen dieses Artikels.