Schnelle und schlanke Anwendungen mit Save-Data

Dave Gash
Dave Gash
Ilya Grigorik
Ilya Grigorik

Mit dem Anfrageheader Save-Data für Client-Hinweise, der in den Browsern Chrome, Opera und Yandex verfügbar ist, können Entwickler schlankere, schnellere Anwendungen für Nutzer bereitstellen, die den Datensparmodus in ihrem Browser aktivieren.

Warum schlanke Seiten wichtig sind

Weblight-Statistiken

Alle sind sich einig, dass schnellere und schlankere Webseiten eine zufriedenstellendere Nutzererfahrung bieten, Inhalte besser verständlich und einprägsam machen und zu mehr Conversions und Umsatz führen. Google-Untersuchungen haben gezeigt, dass „…optimierte Seiten viermal schneller geladen werden als die Originalseite und 80 % weniger Byte verbrauchen. Da diese Seiten so viel schneller geladen werden, konnten wir auch einen Anstieg des Traffics auf diesen Seiten um 50 % verzeichnen.“

Und obwohl die Anzahl der 2G-Verbindungen endlich rückläufig ist, war 2G im Jahr 2015 immer noch die dominierende Netzwerktechnologie. Die Verbreitung und Verfügbarkeit von 3G- und 4G-Netzen nimmt rasant zu, aber die damit verbundenen Kosten und Netzwerkeinschränkungen sind für Hunderte Millionen Nutzer immer noch ein wichtiger Faktor.

Das sind starke Argumente für die Seitenoptimierung.

Es gibt alternative Methoden, um die Websitegeschwindigkeit ohne direkte Beteiligung von Entwicklern zu verbessern, z. B. Proxy-Browser und Transcodierungsdienste. Obwohl solche Dienste recht beliebt sind, haben sie erhebliche Nachteile – einfache (und manchmal inakzeptable) Bild- und Textkomprimierung, Unfähigkeit, sichere (HTTPS) Seiten zu verarbeiten, Optimierung nur von Seiten, die über ein Suchergebnis besucht werden, und mehr. Die Beliebtheit dieser Dienste ist ein Indikator dafür, dass Webentwickler die hohe Nachfrage der Nutzer nach schnellen und einfachen Anwendungen und Seiten nicht richtig erfüllen. Aber der Weg dorthin ist komplex und manchmal schwierig.

Der Anfrageheader Save-Data

Eine recht einfache Methode ist, den Browser mithilfe des Anfrageheaders Save-Data zu nutzen. Durch die Identifizierung dieses Headers kann eine Webseite eine optimierte Nutzererfahrung für Nutzer mit Kosten- und Leistungseinschränkungen bereitstellen.

In den unten aufgeführten unterstützten Browsern können Nutzer einen Datensparmodus aktivieren, der dem Browser die Berechtigung erteilt, eine Reihe von Optimierungen anzuwenden, um die zum Rendern der Seite erforderliche Datenmenge zu reduzieren. Wenn diese Funktion verfügbar ist oder beworben wird, kann der Browser Bilder mit niedrigerer Auflösung anfordern, das Laden einiger Ressourcen verzögern oder Anfragen über einen Dienst weiterleiten, der andere inhaltsspezifische Optimierungen wie die Komprimierung von Bild- und Textressourcen anwendet.

Unterstützte Browser

Einstellung „Save-Data“ wird erkannt

Um festzustellen, wann die „Light“-Version für Nutzer bereitgestellt werden soll, kann Ihre Anwendung den Anfrageheader Save-Data für Client Hints prüfen. Dieser Anfrageheader gibt an, dass der Client eine reduzierte Datennutzung bevorzugt, z. B. aufgrund hoher Übertragungskosten, langsamer Verbindungsgeschwindigkeiten oder aus anderen Gründen.

Wenn der Nutzer den Datensparmodus in seinem Browser aktiviert, hängt der Browser den Anfrageheader Save-Data an alle ausgehenden Anfragen (sowohl HTTP als auch HTTPS) an. Derzeit wird im Header nur ein *on-Token (Save-Data: on) angegeben. Dies kann in Zukunft jedoch erweitert werden, um andere Nutzereinstellungen anzugeben.

Außerdem lässt sich in JavaScript erkennen, ob Save-Data aktiviert ist:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

Es ist wichtig, zu prüfen, ob das connection-Objekt im navigator-Objekt vorhanden ist, da es die Network Information API darstellt, die nur in Chrome, Chrome für Android und Samsung Internet-Browsern implementiert ist. Anschließend müssen Sie nur noch prüfen, ob navigator.connection.saveData gleich true ist, und können dann alle Vorgänge zum Speichern von Daten in dieser Bedingung implementieren.

Der Save-Data-Header in den Chrome-Entwicklertools zusammen mit der Erweiterung „Datensparmodus“.
Aktivieren der Erweiterung „Datensparmodus“ in Chrome für Computer

Wenn Ihre Anwendung einen Service Worker verwendet, kann sie die Anfrageheader prüfen und die entsprechende Logik anwenden, um die Nutzerfreundlichkeit zu optimieren. Alternativ kann der Server im Anfrageheader Save-Data nach den angegebenen Einstellungen suchen und eine alternative Antwort zurückgeben, z. B. anderes Markup, kleinere Bilder und Videos usw.

Tipps und Best Practices für die Implementierung

  1. Wenn du Save-Data verwendest, solltest du einige UI-Geräte bereitstellen, die diese Funktion unterstützen, und Nutzern die Möglichkeit geben, einfach zwischen den Modi zu wechseln. Beispiel:
    • Informieren Sie die Nutzer darüber, dass Save-Data unterstützt wird, und ermutigen Sie sie, es zu verwenden.
    • Ermögliche es Nutzern, den Modus mit entsprechenden Aufforderungen und intuitiven Ein/Aus-Schaltflächen oder Kästchen zu identifizieren und auszuwählen.
    • Wenn der Datensparmodus ausgewählt ist, muss eine einfache und offensichtliche Möglichkeit angeboten werden, ihn zu deaktivieren und bei Bedarf zur vollständigen Nutzung zurückzukehren.
  2. Denken Sie daran, dass schlanke Anwendungen keine minderwertigen Anwendungen sind. Sie lassen keine wichtigen Funktionen oder Daten weg, sondern sind sich nur der damit verbundenen Kosten und der Nutzererfahrung bewusster. Beispiel:
    • Eine Fotogalerie-Anwendung kann Vorschauen mit niedrigerer Auflösung liefern oder einen weniger codeintensiven Karussellmechanismus verwenden.
    • Eine Suchanwendung kann weniger Ergebnisse auf einmal zurückgeben, die Anzahl der medienintensiven Ergebnisse begrenzen oder die Anzahl der Abhängigkeiten reduzieren, die zum Rendern der Seite erforderlich sind.
    • Eine nachrichtenorientierte Website zeigt möglicherweise weniger Artikel, lässt weniger beliebte Kategorien weg oder bietet kleinere Medienvorschauen.
  3. Stelle Serverlogik bereit, um den Anfrageheader Save-Data zu prüfen, und erwäge, eine alternative, einfachere Seitenantwort bereitzustellen, wenn er aktiviert ist. Reduziere beispielsweise die Anzahl der erforderlichen Ressourcen und Abhängigkeiten, wende eine aggressivere Ressourcenkomprimierung an usw.
    • Wenn du eine alternative Antwort basierend auf dem Save-Data-Header bereitstellst, musst du ihn der Vary-Liste (Vary: Save-Data) hinzufügen, um Upstream-Caches mitzuteilen, dass sie diese Version nur dann im Cache speichern und bereitstellen sollen, wenn der Save-Data-Anfrageheader vorhanden ist. Weitere Informationen finden Sie in den Best Practices für die Interaktion mit Caches.
  4. Wenn Sie einen Service Worker verwenden, kann Ihre Anwendung erkennen, ob die Option zum Datensparen aktiviert ist. Dazu wird geprüft, ob der Anfrageheader Save-Data vorhanden ist, oder der Wert des Attributs navigator.connection.saveData wird geprüft. Wenn die Funktion aktiviert ist, sollten Sie überlegen, ob Sie die Anfrage so umschreiben können, dass weniger Byte abgerufen werden, oder ob Sie eine bereits abgerufene Antwort verwenden können.
  5. Sie können Save-Data mit anderen Signalen ergänzen, z. B. mit Informationen zum Verbindungstyp und zur Technologie des Nutzers (siehe NetInfo API). Beispielsweise möchtest du die einfache Version für alle Nutzer mit einer 2G-Verbindung bereitstellen, auch wenn Save-Data nicht aktiviert ist. Umgekehrt bedeutet die Tatsache, dass der Nutzer eine „schnelle“ 4G-Verbindung hat, nicht, dass er nicht am Sparen von Daten interessiert ist – z. B. beim Roaming. Zusätzlich können Sie das Vorhandensein von Save-Data mit dem Client-Hinweis Device-Memory ergänzen, um die Anpassung an Nutzer auf Geräten mit begrenztem Arbeitsspeicher weiter zu verbessern. Der Arbeitsspeicher des Nutzergeräts wird auch im Client-Hinweis navigator.deviceMemory angegeben.

Rezepte

Was Sie mit Save-Data erreichen können, ist nur durch Ihre Vorstellungskraft begrenzt. Damit Sie sich ein Bild davon machen können, was möglich ist, gehen wir ein paar Anwendungsfälle durch. Vielleicht fallen Ihnen beim Lesen noch weitere Anwendungsfälle ein. Probieren Sie einfach aus, was möglich ist.

Serverseitiger Code wird auf „Save-Data“ überprüft

Der Status Save-Data kann zwar in JavaScript über das Attribut navigator.connection.saveData erkannt werden, aber manchmal ist es besser, ihn serverseitig zu erkennen. In einigen Fällen kann die Ausführung von JavaScript fehlschlagen. Außerdem ist die serverseitige Erkennung die einzige Möglichkeit, das Markup zu ändern, bevor es an den Client gesendet wird. Das ist bei einigen der vorteilhaftesten Anwendungsfälle von Save-Data der Fall.

Die genaue Syntax zum Erkennen des Save-Data-Headers im serverseitigen Code hängt von der verwendeten Sprache ab. Die grundlegende Idee sollte jedoch für jedes Anwendungs-Backend gleich sein. In PHP werden Anfrageheader beispielsweise im superglobalen Array $_SERVER unter Indexen gespeichert, die mit HTTP_ beginnen. Das bedeutet, dass Sie den Header Save-Data erkennen können, indem Sie das Vorhandensein und den Wert der Variable $_SERVER["HTTP_SAVE_DATA"] so prüfen:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

Wenn Sie diese Prüfung durchführen, bevor Markup an den Client gesendet wird, enthält die Variable $saveData den Status Save-Data und kann überall auf der Seite verwendet werden. Nachdem wir diesen Mechanismus veranschaulicht haben, sehen wir uns nun einige Beispiele an, wie wir damit die Datenmenge begrenzen können, die wir an den Nutzer senden.

Bilder mit niedriger Auflösung für Bildschirme mit hoher Auflösung bereitstellen

Ein häufiger Anwendungsfall für Bilder im Web ist die Bereitstellung von Bildern in Zweiersets: ein Bild für „Standard“-Bildschirme (1x) und ein anderes Bild, das doppelt so groß ist (2x), für Bildschirme mit hoher Auflösung (z.B. Retina-Display). Diese Klasse von hochauflösenden Bildschirmen ist nicht unbedingt auf High-End-Geräte beschränkt und wird immer häufiger verwendet. Wenn eine schlankere Anwendung bevorzugt wird, kann es sinnvoll sein, Bilder mit niedrigerer Auflösung (1x) an diese Bildschirme zu senden, anstatt größere Varianten (2x). Wenn der Save-Data-Header vorhanden ist, ändern wir einfach das Markup, das wir an den Client senden:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

Dieser Anwendungsfall ist ein perfektes Beispiel dafür, wie wenig Aufwand es ist, jemanden zu berücksichtigen, der Sie ausdrücklich bittet, ihm weniger Daten zu senden. Wenn ihr das Markup im Backend nicht ändern möchtet, könnt ihr dasselbe Ergebnis auch mit einem URL-Rewrite-Modul wie mod_rewrite von Apache erzielen. Es gibt Beispiele dafür, wie Sie dies mit relativ wenig Konfiguration erreichen können.

Sie können dieses Konzept auch auf CSS-background-image-Eigenschaften ausweiten, indem Sie dem <html>-Element einfach eine Klasse hinzufügen:

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

Von hier aus können Sie die Klasse save-data für das Element <html> in Ihrem CSS-Code als Ziel festlegen, um die Auslieferung von Bildern zu ändern. Sie können Hintergrundbilder mit niedriger Auflösung an Bildschirme mit hoher Auflösung senden, wie im obigen HTML-Beispiel gezeigt, oder bestimmte Ressourcen ganz weglassen.

Unwichtige Bilder weglassen

Einige Bildinhalte im Web sind einfach nicht wichtig. Solche Bilder können zwar eine nette Ergänzung zu Inhalten sein, sind aber für Nutzer, die das Beste aus ihren getakteten Datentarifen herausholen möchten, möglicherweise nicht wünschenswert. Im einfachsten Anwendungsfall von Save-Data können wir den PHP-Erkennungscode von oben verwenden und nicht unbedingt erforderliches Bild-Markup ganz weglassen:

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

Diese Technik kann durchaus einen deutlichen Effekt haben, wie Sie in der folgenden Abbildung sehen können:

Ein Vergleich zwischen dem Laden nicht kritischer Bilder, wenn „Save-Data“ nicht vorhanden ist, und dem Weglassen derselben Bilder, wenn „Save-Data“ vorhanden ist.
Vergleich zwischen dem Laden nicht kritischer Bilder, wenn „Save-Data“ nicht vorhanden ist, und dem Weglassen derselben Bilder, wenn „Save-Data“ vorhanden ist.

Natürlich ist das Weglassen von Bildern nicht die einzige Möglichkeit. Sie können auch Save-Data verwenden, um auf das Senden anderer nicht kritischer Ressourcen wie bestimmter Schriftarten zu verzichten.

Nicht unbedingt erforderliche Webschriftarten weglassen

Webschriftarten machen zwar in der Regel nicht annähernd so viel der Gesamtlast einer Seite aus wie Bilder, sind aber dennoch recht beliebt. Sie verbrauchen auch nicht gerade wenig Daten. Außerdem ist die Art und Weise, wie Browser Schriftarten abrufen und rendern, komplizierter, als Sie vielleicht denken. Konzepte wie FOIT, FOUT und Browserheuristiken machen das Rendern zu einem differenzierten Vorgang.

Es liegt also nahe, dass Sie nicht unbedingt erforderliche Webschriftarten für Nutzer weglassen, die eine schlankere Nutzererfahrung wünschen. Mit Save-Data ist das relativ einfach.

Angenommen, Sie haben Fira Sans von Google Fonts auf Ihrer Website eingebunden. Fira Sans ist eine hervorragende Schriftart für den Haupttext, aber vielleicht ist sie für Nutzer, die Daten sparen möchten, nicht so wichtig. Wenn wir dem <html>-Element die Klasse save-data hinzufügen, wenn der Save-Data-Header vorhanden ist, können wir Stile schreiben, die zuerst die nicht wesentliche Schriftart aufrufen, sie dann aber deaktivieren, wenn der Save-Data-Header vorhanden ist:

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

Bei diesem Ansatz können Sie das <link>-Snippet von Google Fonts beibehalten, da der Browser CSS-Ressourcen (einschließlich Webschriftarten) spekulativ lädt. Dazu werden zuerst Stile auf das DOM angewendet und dann wird geprüft, ob HTML-Elemente Ressourcen im Stylesheet aufrufen. Wenn jemand mit aktiviertem Save-Data vorbeikommt, wird Fira Sans nie geladen, da das gestaltete DOM die Schriftart nie aufruft. Stattdessen wird Arial verwendet. Sie ist nicht so schön wie Fira Sans, aber für Nutzer, die ihr Datenvolumen schonen möchten, ist sie möglicherweise besser geeignet.

Zusammenfassung

Der Header Save-Data ist nicht sehr differenziert. Er ist entweder aktiviert oder deaktiviert und die Anwendung muss je nach Einstellung die entsprechenden Inhalte bereitstellen, unabhängig vom Grund.

Beispielsweise erlauben einige Nutzer den Datensparmodus möglicherweise nicht, wenn sie vermuten, dass dadurch App-Inhalte oder -Funktionen verloren gehen, selbst wenn die Verbindung schlecht ist. Andere Nutzer aktivieren sie möglicherweise standardmäßig, um Seiten so klein und einfach wie möglich zu halten, auch wenn die Verbindung gut ist. Am besten ist es, wenn deine App davon ausgeht, dass der Nutzer die vollständige und uneingeschränkte Nutzung wünscht, bis du durch eine explizite Nutzeraktion einen klaren Hinweis auf das Gegenteil erhältst.

Als Websiteinhaber und Webentwickler sollten wir die Verantwortung für die Verwaltung unserer Inhalte übernehmen, um die Nutzerfreundlichkeit für Nutzer mit begrenztem Datenvolumen und Budget zu verbessern.

Weitere Informationen zu Save-Data und hervorragende praktische Beispiele findest du unter Help Your Users Save Data.