Sabine Hamm: graceful degradation vs. progressive enhancement

Beitrag lesen

Originaltitel: graceful degradation vs. progressive enhancement, https://docs.webplatform.org

Zusammenfassung

Dieser Artikel setzt sich mit den wichtigen Konzepten von graceful degradation und progressive enhancement auseinander und wie sie mit JavaScript in Beziehung stehen.

Einführung

In diesem Teil des Web Standards Curriculum diskutieren wir die Unterschiede zwischen zwei Entwicklungsansätzen: graceful degradation und progressive enhancement. Der Einfachheit halber sind hier Arbeitsdefinitionen:

**Graceful degradation**
Eine alternative Version Ihrer Funktionalität anbieten oder den Nutzer auf Einschränkungen eines Produktes aufmerksam machen als Sicherheitsmaßnahme, um zu gewährleisten, dass das Produkt nutzbar ist.
**Progressive enhancement**
Mit einem Grundstock an anwendbarer Funktionalität beginnen, dann Schritt für Schritt den Bedienkomfort des Nutzers erhöhen, indem man vor der Nutzung die Verfügbarkeit besserer Möglichkeiten testet.

Sie denken vielleicht, dass diese beiden Ansätze sehr ähnlich klingen und sie so ziemlich das gleiche Ergebnis haben, aber es gibt Unterschiede, die man beachten sollte und die wir uns im Folgenden ansehen.

Wir beginnen, indem wir den Bedarf an diesen Techniken erklären. Danach sehen wir uns eine umfangreichere Definition an, die Ausführungsbeispiele zeigt und darauf folgt ein Vergleich und eine Faustregel, wann welche Technik anzuwenden ist. Beginnen wir mit der Erklärung, warum wir solche speziellen Entwicklungsansätze in der Web-Entwicklung brauchen.

„Mobilis in mobile“ - in einer sich ständig verändernden Umgebung unterwegs sein

Wie Captain Nemo aus „20 000 Meilen unter dem Meer“ finden sich Web-Entwickler in einer sich ständig verändernden und fluktuierenden Umgebung wieder, die ziemlich widerspenstig gegenüber dem sein kann, was wir zu erreichen versuchen.

Das „Web“ wurde erfunden und dazu gedacht, dass es mit jeglichem Gerät mit Bildschirm, in jeder Sprache und überall genutzt werden konnte. Das einzige, was vom Endnutzer erwartet wird ist, dass er eine Art Browser nutzt, der ins Netz kommt und die zur Übermittlung benutzten Protokolle versteht – http, https, ftp und so weiter.

Das bedeutet, dass wir von den Gegebenheiten und Fähigkeiten des Endnutzers nichts voraussetzen können. Wir können auch ziemlich sicher sein, dass unsere Web-Erfahrung als Entwickler sich vollkommen unterscheidet von der der Menschen, die wir erreichen wollen.

Es gibt kein gesetzlich vorgeschriebenes Upgrade von Technologien, um Internetinhalte zu erreichen. Menschen und Unternehmen werden bei einem festgelegten System bleiben und nichts verändern oder verbessern, nur weil wir wollen, dass sie es tun. Viele Menschen wollen das Web nur „konsumieren“ und bemerken die Technologien dahinter überhaupt nicht – alles, was sie erwarten, ist, dass sie die von uns versprochenen Inhalte erreichen können. Es bleibt den Betriebssystem- und Browser-Entwicklern überlassen, die Endnutzer dazu zu bewegen, ihre Systeme auf dem neuesten Stand zu halten – als Web-Entwickler haben wir dabei kein Mitspracherecht.

All das führt zu einer sehr anfälligen Entwicklungsumgebung, zum Beispiel Büros, in denen der Standard ein 9 Jahre alter Browser ist, bei dem Scripting und Plugins gesperrt sind (aus Sicherheitsgründen), niedrige Auflösung und Computer, die gerade so mit der Office-Software zurechtkommen, sind durchaus üblich.
Wir könnten jetzt hergehen und behaupten, dass diese Unternehmen den Anschluss verpasst hätten und es keinen Sinn ergebe, veraltete Technologien unterstützen zu wollen. Aber diese Haltung kann uns vergessen lassen, dass diese Leute vielleicht sehr wichtig für den Erfolg unserer Produkte sein könnten. In vielen Fällen haben sie nicht die nötigen Rechte, um ihre technische Ausrüstung zu ändern. In Bezug auf Zugänglichkeit sind die Dinge noch offensichtlicher: ein legasthenischer Endnutzer kann unsere verschachtelten Anweisungen nicht verstehen und ein blinder Nutzer kann nicht „den grünen Button anklicken, um weiter zu machen“, obwohl wir bestimmt haben, dass es notwendig ist, um unser System zu nutzen.

Wir arbeiten in unbekannten Bereichen und müssen einen Weg finden, wie das funktionieren kann. Hier kommen sowohl graceful degradation als auch progressive enhancement ins Spiel.

Graceful degradation und progressive enhancement in Kürze

Sie haben bereits eine einfache Definition weiter oben gesehen; in diesem Teil gebe ich eine eher technische Definition und sehe mir an, was es tatsächlich bedeutet, diese Methodik einzuführen.

Also, graceful degradation ist die Praxis, Ihre Web-Funktionalität so aufzubauen, dass sie für einen gewissen Grad an Nutzer-Bedienkomfort mit moderneren Browsern sorgt, aber sie wird auch ohne Weiteres zu einem niedrigeren Grad an Nutzer-Bedienkomfort in älteren Browsern heruntergestuft. („degrade gracefully“) Dieser niedrigere Grad ist für Ihre Website-Besucher nicht so angenehm in der Nutzung, aber er liefert ihnen trotzdem die Basisfunktionalität, wegen deren Nutzung sie auf Ihre Site kamen; die Website ist für sie nicht kaputt.

Progressive enhancement ist ähnlich, aber dabei läuft die Sache anders herum. Sie beginnen mit einem sehr einfachen Grad an Nutzer-Bedienkomfort, den alle Browser bieten können, wenn Ihre Website dargestellt wird, aber Sie integrieren auch komplexere Funktionalität, die automatisch für Browser verfügbar ist, die sie verwenden können.

Mit anderen Worten, graceful degradation beginnt mit dem Status Quo an Komplexität und bemüht sich, mit dem geringeren Bedienkomfort zurechtzukommen, wohingegen progressive enhancement von einem sehr einfachen Arbeitsbeispiel ausgeht und regelmäßige Erweiterungen für zukünftige Umfelder ermöglicht. „Degrading gracefully“ bedeutet zurückzuschauen, wogegen „enhancing progressively“ bedeutet, nach vorne zu sehen und dennoch auf dem Teppich zu bleiben.

“Print this page”–Links

Links, die dem Nutzer ermöglichen, das aktuelle Dokument auszudrucken, sind wohl unnütz – das Druckersymbol ihres Browsers anzuklicken, erfüllt den gleichen Zweck. Nutzer-Tests zeigen jedoch, dass sie für einen letzten Schritt in einem Buchungsvorgang (z.B. auf einer Website einer Fluggesellschaft) eine gute bestätigende Handlungsaufforderung sind. Nutzer empfinden, dass sie die Kontrolle haben und bekommen das Gefühl, das, was sie begonnen haben, auch beendet zu haben.

Das Problem mit “Print this page”–Links ist, dass es in HTML keine Möglichkeit der Verbindung mit dem Print-button des Browsers gibt – dazu braucht man JavaScript. In JavaScript ist es einfach - das window-Objekt des Browsers hat eine Methode print(), die aufgerufen werden kann, um das Dokument zu drucken. Die vermutlich gebräuchlichste Art, das zu tun ist, indem man das Pseudo-Protokoll javascript benutzt:

<p id="printthis">
  <a href="javascript:window.print()">
    diese Seite drucken
  </a>
</p>

Das funktioniert, wenn JavaScript verfügbar und aktiviert ist, und der Browser den Druckauftrag unterstützt. Ist JavaScript jedoch nicht verfügbar (z.B. auf manchen mobilen Geräten), dann funktioniert dieser Link nicht – beim Draufklicken wird überhaupt nichts passieren. Das verursacht ein Problem, denn als Website-Entwickler verspricht man den Besuchern diese Funktion. Wenn sie den Link anklicken und er nicht funktioniert, werden sie sich verwirrt und betrogen fühlen und werden Sie berechtigterweise für einen schlechten Nutzer-Bedienkomfort verantwortlich machen.

Um das weniger problematisch zu gestalten, entscheiden sich Website-Entwickler normalerweise für den Ansatz graceful degradation: dem Nutzer sagen, dass der Link vielleicht nicht funktioniert und warum und möglicherweise sogar eine andere Lösung vorschlagen, um das zu erreichen, was sie wollen. Ein üblicher Trick ist die Verwendung des noscript-Elements. Alles innerhalb dieses Elements wird dem Endnutzer angezeigt, wenn JavaScript nicht verfügbar ist. In unserem Fall könnte das folgendes sein:

<p id="printthis">
  <a href="javascript:window.print()">
    diese Seite drucken
  </a>
</p>
<noscript>
  <p class="scriptwarning">
    Das Drucken dieser Seite erfordert JavaScript.
    Bitte aktivieren Sie JavaScript in Ihrem Browser.
  </p>
</noscript>

Das heißt „degrading gracefully“ – wir erklären dem Endnutzer, das etwas nicht stimmt und wie man das Problem umgehen kann. Allerdings setzt das voraus, dass Website-Besucher:

  • wissen, was JavaScript ist
  • wissen, wie es aktiviert wird
  • die Rechte und Optionen haben, um es zu aktivieren
  • freudig JavaScript aktivieren, nur um ein Dokument zu drucken

Ein etwas besserer Ansatz wäre vielleicht folgendes:

<p id="printthis">
  <a href="javascript:window.print()">diese Seite drucken</a>
</p>
<noscript>
  <p class="scriptwarning">
    So drucken Sie eine Kopie Ihrer Bestellung:
    Wählen Sie das Drucker-Symbol in Ihrem Browser
    oder wählen Sie "drucken" aus dem Menü "Datei".
  </p>
</noscript>

Damit wird man einige der oben beschriebenen Probleme los, aber es setzt voraus, dass die Druckfunktion des Browsers in allen Browsern identisch ist. Dazu bleibt die Tatsache bestehen – das Problem bei dieser Ansatzart ist, dass wir gewisse Funktionen anbieten in vollem Bewusstsein, dass es möglicherweise nicht funktioniert und uns dann rechtfertigen müssen. Technisch gesehen braucht es keinen „print this“-Button, weshalb ein „progressively enhanced“-Ansatz für das gleiche Problem nicht voraussetzt, dass er klappt.

Wenn man dieses Problem unter Verwendung von progressive enhancement lösen wollte, wäre der erste Schritt herauszufinden, ob es eine non-scripting-Möglichkeit gibt, die Seite zu drucken. Diese gibt es nicht, was nun bedeutet, dass die Verwendung eines Links die falsche Wahl eines HTML-Elements ist. Wenn man Funktionen bieten möchte, die nur mit JavaScript verfügbar sind, sollte man Buttons benutzen: per Definition sind Buttons für die Unterstützung der scripting-Funktion da. In der W3C-Spezifikation heißt es:

Buttons haben kein Standardverhalten, sie können über bestimmte Ereignisse mit einem clientseitigem Script verbunden sein. Wenn ein Ereignis eintritt (der Button wird gedrückt oder losgelasssen oder ...) wird das Script ausgeführt.

Der zweite Schritt ist, nicht davon auszugehen, dass der Nutzer JavaScript aktiviert hat und der Browser drucken kann. Stattdessen sagen wir den Nutzern einfach rundheraus, dass sie das Dokument drucken sollen und überlassen ihnen das „wie“:

<p id="printthis">
  Vielen Dank für Ihre Bestellung. 
  Bitte drucken Sie dieses Dokument
  für Ihre Unterlagen aus.
</p>

Das funktioniert in jedem Fall. Für den Rest der Funktionen benutzen wir unauffälliges JavaScript, um einen print-Button einzufügen falls der Browser das unterstützt:

<p id="printthis">
  Vielen Dank für Ihre Bestellung. Bitte drucken Sie
  dieses Dokument für Ihre Unterlagen aus.
</p>
<script>
(function(){
  if(document.getElementById){
    var pt = document.getElementById('printthis');
    if(pt && typeof window.print === 'function'){
      var but = document.createElement('input');
      but.setAttribute('type','button');
      but.setAttribute('value','diese Seite drucken');
      but.onclick = function(){
        window.print();
      };
      pt.appendChild(but);
    }
  }
})();
</script>

Beachten Sie, wie defensiv das Script ist – wir setzen gar nichts voraus.

  • Indem die ganze Funktionalität in eine anonyme Funktion gepackt und sofort ausgeführt wird – das bewirkt „(function(){})()“ – wird keine globale Variable hinterlassen.
  • Wir probieren DOM-Unterstützung aus und versuchen, das Element zu bekommen, an das wir den Button anhängen wollen.
  • Wir testen dann, ob das Element existiert und ob der Browser ein window-Objekt und eine print methode hat (indem wir prüfen, ob der Typ dieser Eigenschaft function ist).
  • Wenn beides zutrifft, erstellen wir einen neuen Button und setzen window.print() als clickevent-Handler ein<./li>
  • Im letzten Schritt fügen wir den Button zum Absatz hinzu.

Das klappt bei jedem Nutzer unabhängig vom technischen Umfeld. Wir versprechen dem Nutzer niemals ein Interface-Element, das nicht funktioniert, sondern zeigen es nur, wenn es funktioniert.

Wann verwendet man was?

Vielleicht bin ich ein Idealist, aber ich mag die Idee graceful degradation wirklich nicht. Wenn ich etwas aufbaue und es in anderer Umgebung dann gerade so zum Laufen bringe (oder den Nutzer zum Update auffordere) gehe ich von ziemlich vielen Voraussetzungen sowohl im Hinblick auf die Umgebung als auch auf die Fähigkeiten des Nutzers beim upgraden aus.

Ich ertappe mich dabei, meinen Blackberry zu benutzen, wenn mein Laptop kein drahtloses Netzwerk finden kann und werde sehr frustriert, wenn Web-Produkte mir sagen, sie bräuchten aktiviertes JavaScript und ich sollte es einschalten. Kann ich nicht, und ich bin mit Sicherheit ein qualifizierter Nutzer ihrer Produkte – besonders, da ich eine Menge Geld für den GPRS- oder EDGE-Zugang zu ihren Diensten zahle.

In ein paar Situationen wird graceful degradation jedoch tragfähig:

  • Sie rüsten ein altes Produkt auf und haben weder die Zeit noch den Zugang noch den Einblick um es zu verändern oder zu ersetzen.
  • Sie haben einfach nicht die Zeit, ein Produkt komplett mit progressive enhancement zu beenden (oft ein Zeichen schlechter Planung oder von Geldmangel).
  • Das Produkt, das Sie haben, ist ein Grenzfall, z.B. Sites mit sehr hohen Besucherzahlen, wo eine Millisekunde an Leistung einen Unterschied von Millionen Dollar ausmacht.
  • Ihr Produkt ist per Definition so abhängig von Scripting, dass es mehr Sinn ergibt, eine Basisversion beizubehalten als eine zu erweitern (Karten, Email-Programme, feed reader)

In allen anderen Fällen wird progressive enhancement sowohl den Endnutzer als auch Sie glücklicher machen:

  • Unabhängig von Umfeld und Fähigkeiten liefern Sie ein Produkt, das funktioniert.
  • Wenn ein neuer Browser herauskommt oder eine Browsererweiterung weitgehend angenommen wird, können Sie immer noch auf ein anderes Level erweitern, ohne die ursprüngliche Lösung anzutasten - graceful degradation würde verlangen, dass Sie die ursprüngliche Lösung ändern.
  • Sie lassen Technologie das sein, was sie sein sollte – eine Hilfe, um ein Ziel damit schneller als ohne zu erreichen, nicht ein „Muss“ um überhaupt in der Lage zu sein, das Ziel zu erreichen.
  • Wenn Sie neue Funktionen hinzufügen müssen, können Sie das tun, nachdem Sie überprüft haben, ob sie ab einem gewissen Stadium unterstützt werden, oder Sie können sie auf dem niedrigsten Level an Funktionalität hinzufügen und sie in komplexeren Umfeldern verbessern. Auf jeden Fall geschieht die Wartung an der gleichen Stelle und nicht an zwei verschiedenen. Ein progressive enhancement-Produkt auf dem Laufenden zu halten, bedeutet weit weniger Arbeit als zwei Versionen zu warten.

Übungsfragen

  • Der Artikel zeigte „print links“ als Beispiel bei dem beide Ansätze angewendet werden könnten. Welche anderen Beispiele fallen Ihnen ein?
  • Nehmen wir an, Sie möchten JavaScript verwenden, um sicherzustellen, dass ein Formularfeld eine Email-Adresse enthält, bevor das Formular gesendet wird. Was wären die verschiedenen Ansätze und welche anderen Probleme müssten bedacht werden?
  • Nehmen wir an, Sie möchten eine Karte anzeigen und progressive enhancement anwenden. Von welcher Grundfunktion würden Sie ausgehen?
  • Nehmen wir an, Sie haben ein Interface, das aus zwei Dropdown-Formelementen besteht. Die Optionsauswahl in der ersten wird die verfügbaren in der zweiten verändern. Was könnte ein Ersatz für diese Art Kontrolle sein? Welche Probleme könnten dabei auftreten?

Über den Artikel

Das Original stammt von Christian Heilmann, christianheilmann.com, die Übersetzung von Sabine Hamm, sabinehamm-uebersetzungen.de. Ebenso wie das Original steht auch die Übersetzung unter einer Creative Commons Lizenz CC BY 3.0 DE.

Über die Lizenz

Die essentiellen Punkte dieser Lizenz sind

  • Sie dürfen:
    • das Werk bzw. den Inhalt vervielfältigen, verbreiten und öffentlich zugänglich machen
    • Abwandlungen und Bearbeitungen des Werkes bzw. Inhaltes anfertigen
  • Zu den folgenden Bedingungen:
    • Namensnennung — Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
    • Weitergabe unter gleichen Bedingungen — Wenn Sie das lizenzierte Werk bzw. den lizenzierten Inhalt bearbeiten, abwandeln oder in anderer Weise erkennbar als Grundlage für eigenes Schaffen verwenden, dürfen Sie die daraufhin neu entstandenen Werke bzw. Inhalte nur unter Verwendung von Lizenzbedingungen weitergeben, die mit denen dieses Lizenzvertrages identisch, vergleichbar oder kompatibel sind.
  • Gewünschte Namensnennung:
    • "Quelle: SELFHTML, Übersetzung: Sabine Hamm", ohne Anführungszeichen, dabei ist auf diesen Artikel zu verlinken.
    • Die Adresse zu diesem Artikel lautet: https://blog.selfhtml.org/2015/jul/15/1-graceful-degradation-vs-progressive-enhancement