Handlungsempfehlungen "Green Web" für Entwickler

HTTP-Caching auf der Server-Seite unterstützen

Die Caching-Möglichkeiten, die im HTTP-Protokoll definiert sind, sind so entworfen, dass sie sowohl die Anzahl der versendeten HTTP-Anfragen als auch das übertragene Datenvolumen signifikant verringern können.

Web-Inhalte, die von serverseitigen Skripten und Programmen dynamisch erzeugt werden, werden aber üblicherweise nicht als Cache-bar behandelt. Dementsprechend werden die zugehörigen Meta-Informationen häufig ganz weggelassen oder so eingestellt, dass sie ein Caching verbieten.

Es kann aber auch Fälle geben, in denen sich die dynamisch erstellten Inhalte weniger häufig ändern, sodass sie nicht für jede HTTP-Anfrage erneut generiert werden müssen. Hier ist dann ein Caching möglich, ohne dass man Gefahr läuft den Besuchern ungültige Daten zu präsentieren.

Dabei sind insbesondere die folgenden Aktivitäten zu betrachten:

  • Abfrage der zu präsentierenden Inhalte aus Content-Repositorien
  • Darstellung dynamisch generierter Schaubilder als Grafiken

In Bezug auf den ersten Punkt ist festzustellen, dass ausgewachsene Content Management Systeme (CMS) ein HTTP-Caching unterstützen. Sie sollten deshalb so konfiguriert werden, dass diese Caching-Strategien auch angewendet werden. D. h., dass eine Unterstützung für Expires sowie Last-Modified Header und oder ETags aktiviert wird.

Eine entsprechende Caching-Unterstützung fehlt aber häufig in Webseiten bzw. Webanwendungen, die direkt in Skripten und Programmen selbst implementiert wurden und nicht über ein CMS betrieben werden. Ein Beispiel dafür ist eine webbasierte Anwendung, die Stromzählerstände eines Einfamilienhauses abruft, die Verbräuche täglich berechnet und als Grafik auf einer Webseite präsentiert. Anstatt bei jeder Anfrage die Grafik neu zu berechnen könnte auch eine Strategie gewählt werden, bei der die Daten nur dann neu berechnet und die Grafik übertragen werden, wenn neue Daten vom System erfasst worden sind. So wäre es z. B. möglich, das Last-Modified-Datum im HTTP-Header auf das Datum bzw. die Uhrzeit zu setzen, zu dem/zu der der jüngste Verbrauchswert in die Datenbasis eingefügt worden ist.

Wir empfehlen Webentwicklern daher in ihren Webanwendungen und Skripten eine Unterstützung für Expires und Last-Modified Header zu implementieren, um das übertragene Datenvolumen gering zu halten und dadurch elektrische Energie einzusparen, soweit das möglich ist. Das folgende Beispiel zeigt, wie eine solche Unterstützung prinzipiell mit der Skriptsprache PHP umgesetzt werden könnte. Ausführlichere Beispiele auch für anderer Programmiersprachen gibt Nottingham (2010).

header('Expires: ' . toGMT($expires));
header('Last-Modified: '.toGMT($lastMod));
if(!isModifiedSince($lastMod)) {
header('HTTP/1.1 304 Not Modified');
exit();
} echo 'ANY CONTENT';

Zunächst wird der Expires Header auf ein Datum/eine Uhrzeit gesetzt, das/die noch vertretbar ist, um für die Art des darzustellenden Inhalts dessen Aktualität sicherzustellen. Der Last-Modified Header wird auf ein Datum/eine Uhrzeit gesetzt, die anzeigt, wann die zugrundeliegenden Inhalte zuletzt geändert wurden. Nachdem die Header-Werte gesetzt sind, wird der Last-Modified-Since Header des aktuellen HTTP-Request mit dem Last-Modified-Datum des Inhalts verglichen. Ist der Inhalt des Browser-Cache immer noch gültig, so wird mit dem HTTP-Status "Not-Modified" geantwortet, ansonsten wird mit dem HTTP-Status "OK" geantwortet und der Inhalt wird erneut übertragen.

JavaScript Minimieren

JavaScript wird heute häufig eingesetzt, um die Interaktivität von Webseiten zu erhöhen. Dabei werden JavaScript Fragmente entweder direkt in den HTML-Code der Webseiten eingebettet oder aber in speziellen JavaScript-Dateien abgelegt. Ersteres vergrößert die Größe der HTTP-Antwort während letzteres die Anzahl der notwendigen HTTP-Anfragen erhöht, insbesondere dann, wenn mehrere JavaScript-Dateien in einer Webseite verwendet werden. Um die Größe des HTML-Inhalts zu minimieren, empfehlen wir direkt in HTML eingebetteten JavaScript-Code in spezielle JavaScript-Dateien auszulagern. Dadurch wird zwar auf der einen Seite eine zusätzlicher HTTP-Anfrage notwendig um diese Datei herunterzuladen, auf der anderen Seite wird so aber

  1. der Web-Browser in die Lage versetzt, diese Dateien zu cachen, wodurch sie in nachfolgenden Anfragen nicht erneut übertragen werden müssen und
  2. die Größe der HTML-Datei wird verringert, insbesondere dann, wenn der HTML-Inhalt nicht im Cache vorgehalten werden kann, weil er für jede Anfrage neu berechnet werden muss.

Wenn Java-Skript-Code in speziellen Dateien vorgehalten wird, empfehlen wir für diese Dateien spezielle Regeln für die automatische Generierung des Expires Header im Webserver zu konfigurieren, sodass diese Dateien weiter in der Zukunft ungültig werden, als der HTML-Inhalt (unter der Annahme, dass sich das technische Rahmenwerk weniger häufig ändert als die präsentierten Inhalte).

Werden von einer Webseite mehrere JavaScript-Dateien verwendet, können HTTP-Anfragen eingespart werden, indem diese Dateien zu einer einzigen Datei zusammengefasst werden. Trotz der sich daraus ergebenden größeren JavaScript-Datei ergibt sich für die Webseite insgesamt eine (wenn auch kleine) Einsparung dadurch, dass nur noch eine Anfrage abgesendet werden muss und in nachfolgenden Anfragen auch nur noch die Gültigkeit dieser einen Datei vom Webbrowser überprüft werden muss, wenn z. B. der Benutzer den Knopf zum "Neu-laden" betätigt.

Die Größe der JavaScript-Datei kann signifikant verkleinert werden, indem nicht benötigte Zeichen, wie z. B. Leerzeichen oder Kommentare, entfernt werden. Sie kann weiter reduziert werden, indem alle Funktionen, Methoden oder Code-Blöcke entfernt werden, die innerhalb eine bestimmten Webseite nicht benötigt werden. Dies trifft vor allem auf Webseiten zu, die nur einen kleinen Teil der Funktionalität umfassender JavaScript-Bibliotheken verwenden.

Eine andere Technik ist "Obfuscation" (Entstellung). Die meisten der dazu verfügbaren Werkzeuge führen zunächst eine Minimierung durch (s. o.) und verkleinern dann erst den JavaScript-Code. Dabei werden z. B. Variablen-, Methoden-, Funktions- und Parameterbezeichner durch kürzere Namen ersetzt. Bezeichner auf die von HTML aus referenziert wird, wie z. B. selbstdefinierte Funktionsnamen oder API-Aufrufe, müssen natürlich unverändert bleiben.

Tabelle 1: Minimierung vs. Obfuscation vs. HTTP-Kompression
prototype-1.6.0.3.js Unkomprimiert (KB) GZIP komprimiert (KB)
Gesamtgröße 126,70 28,49
Minimierte größe
JSMin
93,09 22,71
Obfuscated größe
Dojo ShrinkSafe
87,66 24,94

Tabelle 1 stellt die Minimierung und Obfuscation der bekannten JavaScript-Bibliothek Prototype (http://www.prototypejs.org/) der HTTP-Kompression gegenüber. Dabei kommt für die Minimierung das Werkzeug JSMin (http://javascript.crockford.com/) und für die Obfuscation das Werkzeug ShrinkSafe aus dem bekannten Dojo Toolkit (http://www.dojotoolkit.org/) zum Einsatz. Wie zu sehen ist, ist für die hier ausgewählten Werkzeuge die Obfuscation effektiver als die Minimierung. Das liegt darin begründet, dass im Gegensatz zur Obfuscation die Minimierung keine Funktionsnamen bzw. Bezeichner durch kürzere Versionen ersetzt. An die Effektivität der HTTP-Kompression mit GZIP kommen beide Werkzeuge jedoch nicht heran. In Kombination mit GZIP erweist sich die vermeintlich effektivere Obfuscation sogar als nachteilig, weil durch die Textersetzungen weniger Wiederholungen im JavaScript-Code zurückbleiben, wodurch niedrigere Kompressionsraten erzielt werden als in der Kombination von Minimierung und GZIP. Weitere Vergleiche mit anderen JavaScript-Bibliotheken, wie z. B. dem Dojo-Toolkit oder script.aculo.us, führten zu ähnlichen Ergebnissen.

Vor diesem Hintergrund wird empfohlen, JavaScript-Dateien mit einem Werkzeug wie JSMin zu minimieren und die HTTP-Antwort mir GZIP (HTTP-Kompression) zu komprimieren, um niedrigere Datentransfervolumina zu erreichen. Die Obfuscation sollte in Szenarios verwendet werden, in denen die HTTP-Kompression nicht angewendet werden kann (z. B. wenn HTTP-Clients/Web-Browser nicht mit der HTTP-Kompression kompatibel sind).

Zusätzlich ist zu empfehlen, die Minimierung und die Obfuscation anzuwenden, bevor die Dateien auf den Server "deployed" werden anstatt dies für jede HTTP-Anfrage dynamisch durchzuführen, was Rechenzeit und somit Energie einspart.

Cascading Style Sheets (CSS) minimieren und optimieren

Das Minimieren und Optimieren der CSS-Dateien bietet viele Möglichkeiten, um das Datentransfervolumen zu reduzieren. Zum Teil kann CSS als Ersatz für JavaScript und HTML verwendet werden. Damit können Ersparnisse von 40% bis zu 60% erzielt werden (vgl. King 2008, S. 177). Durch auf CSS basierenden Layouts können 25% bis 50% der Dateigröße der äquivalenten HTML-Dateien eingespart werden (vgl. King 2008, S. 180).

Die Tabelle 2 zeigt die Dateigröße mit einer CSS-Datei, die mit dem Werkzeug CSSTidy (http://csstidy.sourceforge.net/) in verschiedenen Stärken minimiert bzw. optimiert wurde. Das Werkzeug verwendet dabei verschiedenen Techniken, um CSS-Dateien zu optimieren.

Tabelle 2: Vergleich der CSS-Dateigrößen nach der Minimierung mit CSSTidy
Ohne Minimierung 2.812 Byte
Standard Minimierung 2.181 Byte
Hohe Minimierung 2.040 Byte
Beste Minimierung 2.021 Byte

In der Standardeinstellung versucht das Werkzeug einen Mittelweg zwischen Größe und Lesbarkeit der CSS-Datei zu gehen. In dieser Einstellung ist die optimierte Datei 631 Byte kleiner als die ursprüngliche Datei. Die Kompressionsrate beträgt damit 22,4%. Das Werkzeug wendet dabei u. a. Abkürzungen von z. B. Farbwerten an. So kann die lange Farbdefinition {color:#ffcc00} kann als {color:#fc0} geschrieben werden.

In der zweiten (hohe) Minimierungseinstellung ist die Datei trotz kleinerer Dateigröße noch gut lesbar. Die Beispieldatei wurde hier um 27,5% verkleinert. Zusätzlich zu den Abkürzungen werden unnötige Leerzeichen, Zeichenketten und Leerzeilen entfernt. Dies verringert zwar die Dateigröße, beeinflusst aber auch die Lesbarkeit.

Die dritte (beste) Minimierungseinstellung führt zur kleinsten Dateigröße. Hier wird auf die Lesbarkeit keine Rücksicht genommen. Es werden zusätzlich zu den vorgenannten Optimierung auch noch die Zeilenumbrüche entfernt, wodurch der gesamte Dateiinhalt in einer Zeile steht. Die Beispieldatei wurde um 28,1% verkleinert.

Neben diesen Möglichkeiten gibt es weitere Möglichkeiten, um CSS zu optimieren. So können z. B. Inline-Styles durch Typ-Selektoren ersetzt werden, nicht benötigter Code kann entfernt werden oder es können anstelle von Inline-Klassen kontextuelle Selektoren verwendet werden. Mit CSS können mehrfache Selektoren mit der gleichen Deklaration gruppiert werden oder es können mehrere Deklarationen mit dem gleichen Selektor in einem Regelsatz definiert werden. Doppelte Elementdeklarationen können mittels Vererbung vermieden werden. Bestimmte Eigenschaftsdeklarationen können abkürzend in einer Deklaration zusammengefasst werden, wie z. B. margin, border, font, background, list-style und outline.

Da lange oder sprechende Klassennamen und IDs nur für Entwickler wichtig sind, nicht aber für die Anwender/Betrachter des Webangebots, sollten Klassennamen oder IDs sollten so kurz wie möglich sein und ggf. abgekürzt werden. Für Entwickler sollten auch die kurzen oder abgekürzten Klassennamen und IDs innerhalb des betreffenden Kontextes handhabbar sein.

CSS-Deklarationen sollten prinzipiell in CSS-Dateien ausgelagert und diese dann in Webseiten eingebunden werden. Das verringert zum einen die Dateigröße der Webdokumente und zum anderen werden die CSS-Deklarationen nur einmal geladen und nicht für jede nachfolgende Anfrage mit dem dynamisch generierten Webdokument erneut übertragen.

CSS kann aber auch eingesetzt werden, um weniger effizienten HTML-Code zu ersetzen. Ein Beispiel ist die Tabellendefinition in HTML. Ein weiteres Beispiel ist die Verwendung eingebetteter JavaScript-Fragmente, die von 84,4% der Webseiten verwendet werden. Beide können häufig durch effizienteren CSS-Code ersetzt werden (vgl. King 2008, S. 177).

Grafische Gestaltelemente und Logos optimieren

Im allgemeinen bestehen moderne Webseiten zu 54% aus Grafiken (vgl. King 2008, S. 157). Diese Grafiken zu optimieren ist daher ein vielversprechender Weg, um das übertragene Datenvolumen zu verringern.

Anders als ein Foto ist ein Logo ein grafisches Objekt, das eine Firma oder eine Organisation symbolisiert. Logos werden meistens mehrfach auf einer Webseite eingebunden. Das Optimieren von Logos kann daher zu höheren Einsparungen führen, als z. B. das Optimieren von Fotos, die meistens nur einmal in einer Seite eingebunden sind.

Ein Logo ist typischerweise kein Foto und im Vergleich zu diesen kleiner, sodass es als verlustfrei als im GIF oder PNG-Format gespeichert werden kann. PNG hat im Vergleich zu GIF einen besseren Kompressionsalgorithmus. Insbesondere bei Grafiken mit indizierten Paletten führt es zu 10% bis 30% kleineren Dateien als das GIF-Format (vgl. King 2008, S. 169).

Logos können relativ einfach optimiert werden, z. B. indem der Farbmodus von RGB-Vollfarben zu einer indexierten Palette geändert wird, die PNG-Kompressionsstufe erhöht wird oder der in den Grafiken enthaltene Text externalisiert direkt mittels HTML und CSS umgesetzt wird.

logo_rgb.png

Abbildung 1: Original-Logo in RGB-Vollfarben

Das im folgenden beispielhaft optimierte Logo besteht aus einem grafischen Objekt, einem Hintergrund mit einem Farbverlauf und einem Text (siehe Abbildung 1). Im ersten Schritt werden die Farben von RGB-Vollfarben auf eine indizierte Palette reduziert. In diesem speziellen Fall ist eine Reduktion auf sechs Farben möglich. Tabelle 3 zeigt die Dateigrößen nach den angewendeten Optimierungsschritten.

Tabelle 3: Vergleich der PNG-Dateigrößen nach der Optimierung
Original-Logo in RGB-Vollfarben 16.959 Byte
Logo in 16 Farben 2.956 Byte
Logo in 6 Farben 1.984 Byte
Logo in 4 Farben ohne Text 604 Byte

Im nächsten Schritt wird der Text in der Grafik durch einen mit CSS formatierten HTML-Text ersetzt. Dazu wird zunächst der grafische Text aus dem Bild gelöscht. Danach wird die Grafik mittels CSS als Hintergrundbild eines HTML-Div-Elements das den Text enthält definiert. Die Dimensionen des Div-Elements muss gleich der Größe des Hintergrundbildes sein. Der CSS-Code für das Beispiel sieht damit so aus:

div.logo {
margin: 0;
width: 370px;
height: 64px;
padding: 10px 70px;
font: 700 21px "Arial Narrow","Arial",sans-serif;
color: #000;
background-image: url("logo.png");
background-repeat: no-repeat;
}

Das sich so ergebende Logo zeigt Abbildung 2. Durch das entfernen des Texts aus der Grafik konnte die Anzahl der Farben auf lediglich vier Farben reduziert werden. Insgesamt konnte somit die Dateigröße von ursprünglich 16.959 Bytes auf 604 Bytes reduziert werden, was einer Reduktion von 96% entspricht.

Software Development Platform
Umwelt-Campus Birkenfeld

Abbildung 2: Endgültiges Logo mit Vierfarbpalette und CSS-formatierter Schrift

Grafikdateien mit ein Pixel großen Bildern, werden häufig verwendet, um für einen bestimmten Seitenbereich eine durch die Bildgröße definierten Ausdehnung zu erzwingen. Solche Grafiken können durch CSS und HTML ersetzt werden, indem Platzhalter die gleiche Funktion erfüllen, wie die Grafiken. So kann ein äquivalentes Layout erreicht werden, ohne dass dafür Grafiken notwendig sind, die heruntergeladen werden müssen.

Grafiken, die immer unmittelbar nebeneinander dargestellt werden, können zu einer Grafikdatei zusammengefasst werden. Image-Maps können dann verwendet werden, wenn die Grafiken für unterschiedliche Links verwendet werden. So kann der gleiche Effekt wie mit einzelnen Grafiken erzielt werden (vgl. King 2008, S. 165).

Für Symbole besteht eine Möglichkeit darin, diese zu sog. CSS-Sprites zusammenzufassen. CSS-Sprites können sehr effektiv sein, wenn viele Symbole in einer Webseite verwendet werden. Dabei wird der für ein einzelnes Symbol benötigte Bildausschnitt mit einer Background-Position-Regel so definiert, dass nur dieses eine Symbol sichtbar ist (vgl. Souders 2007).

Fotos optimieren

Die Dateigröße von Fotos und Werbebannern ist meistens größer als die Dateigröße eines Logos. Im Allgemeinen sollten Fotos mit an das Web angepassten Einstellungen gespeichert werden. Außerdem sollte die Bildgröße der gewünschten Darstellungsgröße entsprechen, sodass nicht unnötig große Bilddateien übertragen werden (d. h., die Bilder nicht durch den Webbrowser auf die gewünschte Größe skalieren lassen).

Fotos werden üblicherweise im verlustbehafteten JPEG-Format gespeichert. Der JPEG-Kompressionsalgorithmus beruht stark vereinfacht ausgedrückt auf Farbgradienten. Ein einfaches Weichzeichnen unterstützt dieses Verfahren und führt zu einer kleineren Dateigröße. Dies kann insbesondere für Bilder eingesetzt werden, in denen der Detailreichtum bestimmter Bereiche weniger Wichtig ist als der anderer Bereiche und diese daher weichgezeichnet werden können (vgl. King 2008, S. 169).

ad-photo-normal-80.jpg

Abbildung 3: Fotografie in 80% JPEG-Qualität

Abbildung 3 zeigt ein Bild bzw. ein Werbefoto in 80% JPEG-Qualität mit einer Dateigröße von 34.567 Bytes. Durch Weichzeichnen des Hintergrunds (mit einem Radius von acht Pixeln) konnte die Dateigröße auf 18.162 Bytes verkleinert werden (siehe Abbildung 4). Die Person im Vordergrund wird immer noch in ausreichender Qualität dargestellt, wohingegen der weniger wichtige Hintergrund weichgezeichnet wurde. Die Hauptinformation des Bildes (Person und blauer Banner für z. B. Werbeslogan) bleibt aber erhalten.

ad-photo-blurred-80.jpg

Abbildung 4: Fotografie mit 80% JPEG-Qualität und weichgezeichnetem Hintergrund

Videos und Animationen optimieren

Multimedia-Dateien, wie z. B. Videos machen 96% des im Internet übertragenen Datenvolumens aus (vgl. King 2008, S. 159). Daher sollte insbesondere diese Dateitypen optimiert werden, um das Datentransfervolumen zu verringern. Hierzu können spezielle Web-Einstellungen und Codecs angewendet werden, die Frame-Rate kann verringert werden oder es kann eine professionelle Ausrüstung bei der Aufnahme (insbesondere Beleuchtung und Stativ) und Produktion der Multimedia-Inhalte verwendet werden.

Andere Typen von Multimedia-Dateien sind Flash-Animationen. Diese können ebenfalls verkleinert und optimiert werden. Hier können insbesondere nicht optimierte Bilder und zu hohe Frameraten zu einem höheren Datenvolumen führen. Deshalb sollten Bilder mit entsprechenden Bildbearbeitungsprogrammen bearbeitet werden, bevor sie importiert werden. Außerdem sollte eine niedrige Framerate eingestellt werden (vgl. King 2008, S. 170).

Quellen- und Literaturverzeichnis

  • King, A. B. (2008): Website optimization. O'Reilly, Beijing.
  • Nottingham, M. (2010): Caching Tutorial. for Web Authors and Webmasters. [Online].
    Verfügbar unter: http://www.mnot.net/cache_docs/ [Letzter Abruf: 19.04.2010].
  • Souders, S. (2007): High performance web sites. Essential knowledge for frontend engineers. O'Reilly, Beijing.

Danksagung

Teile dieses Textes wurden durch INSTICC Press veröffentlicht:

  • Dick, Markus; Naumann, Stefan; Held, Alexandra: Green Web Engineering. A Set of Principles to Support the Development and Operation of "Green" Websites and their Utilization during a Website’s Life Cycle. Filipe, Joaquim; Cordeiro, José (Hrsg.): WEBIST 2010 : Proceedings of the 6th International Conference on Web Information Systems and Technologies, April 7 - 10, 2010, Valencia, Spain, Volume 1. Setúbal: INSTICC Press, 2010, S. 48 - 55.