Best Practices für eine schnellere Web-App mit HTML5

Einleitung

Ein Großteil von HTML5 zielt darauf ab, native Browserunterstützung für Komponenten und Techniken zu bieten, die wir bisher mithilfe von JavaScript-Bibliotheken erreicht haben. Die Verwendung dieser Funktionen kann, sofern vorhanden, zu einer deutlich schnelleren Nutzererfahrung führen. In dieser Anleitung fasse ich nicht die herausragenden Studien zur Leistung zusammen, die Sie auf der Website mit außergewöhnlicher Leistung von Yahoo oder in den Page Speed-Dokumenten von Google gesehen haben, und auch nicht auf der Website Let's make the web faster. Stattdessen werde ich mich auf die Verwendung von HTML5 und CSS3 konzentrieren, damit Ihre Webanwendungen schneller reagieren.

Tipp 1: Webspeicher anstelle von Cookies verwenden

Cookies werden zwar schon seit Jahren verwendet, um Daten einzelner Nutzer zu erfassen, haben aber erhebliche Nachteile. Der größte Nachteil besteht darin, dass alle Cookie-Daten in jedem HTTP-Anfrage-Header enthalten sind. Dies kann sich am Ende messbar auf die Reaktionszeit auswirken, insbesondere bei XHRs. Es hat sich daher bewährt, die Größe von Cookies zu reduzieren. In HTML5 können wir das sogar noch besser: Verwenden Sie sessionStorage und localStorage anstelle von Cookies.

Diese beiden Webspeicherobjekte können verwendet werden, um Nutzerdaten clientseitig für die Dauer der Sitzung oder für unbestimmte Zeit zu speichern. Auch werden ihre Daten nicht bei jeder HTTP-Anfrage an den Server übertragen. Sie haben eine API, mit der Sie auf Cookies verzichten können. Im Folgenden sehen Sie beide APIs, die Cookies als Fallback verwenden.

// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {

  // easy object property API
  localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';

} else {

  // without sessionStorage we'll have to use a far-future cookie
  //   with document.cookie's awkward API :(
  var date = new Date();
  date.setTime(date.getTime()+(365*24*60*60*1000));
  var expires = date.toGMTString();
  var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
                  ' expires='+expires+'; path=/';
  document.cookie = cookiestr;
}

Tipp 2: CSS-Übergänge anstelle von JavaScript-Animationen verwenden

CSS-Übergänge sorgen für einen ansprechenden visuellen Übergang zwischen zwei Status. Die meisten Stileigenschaften können übertragen werden, z. B. den Textschatten, die Position, den Hintergrund oder die Farbe bearbeiten. Sie können Übergänge in Pseudo-Selektorstatus wie :hover oder von HTML5-Formularen :invalid und :valid verwenden (Beispiel mit Formularvalidierungsstatus). Aber sie sind wesentlich leistungsfähiger und können ausgelöst werden, wenn Sie einem Element eine beliebige Klasse hinzufügen.

div.box {
  left: 40px;
  -webkit-transition: all 0.3s ease-out;
     -moz-transition: all 0.3s ease-out;
       -o-transition: all 0.3s ease-out;
          transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }

Wenn Sie zwischen den Klassen von totheleft und totheright wechseln, können Sie das Feld verschieben. Vergleichen Sie diese Codemenge mit der einer JavaScript-Animationsbibliothek. Offensichtlich ist die Anzahl der an den Browser gesendeten Byte bei CSS-basierten Animationen deutlich geringer. Außerdem verlaufen diese visuellen Übergänge dank der Beschleunigung auf GPU-Ebene so reibungslos wie möglich.

Tipp 3: Clientseitige Datenbanken anstelle von Server-Roundtrips verwenden

Mit Web SQL Database und IndexedDB werden Datenbanken auf Clientseite eingeführt. Anstelle des üblichen Musters des Postens von Daten auf dem Server über XMLHttpRequest oder der Übermittlung von Formularen können Sie diese clientseitigen Datenbanken nutzen. Die Reduzierung von HTTP-Anfragen ist eines der Hauptziele aller Performance Engineers. Wenn sie als Datenspeicher verwendet werden, können also viele Fahrten über XHR gespart oder Posts an den Server gesendet werden. localStorage und sessionStorage konnten in einigen Fällen verwendet werden, z. B. zum Erfassen des Fortschritts von Formularübermittlungen. Sie haben sich dadurch als deutlich schneller als die clientseitigen Datenbank-APIs erwiesen. Wenn Sie beispielsweise eine Datenraster-Komponente oder einen Posteingang mit Hunderten von Nachrichten haben und die Daten lokal in einer Datenbank speichern, sparen Sie HTTP-Roundtrips, wenn der Nutzer suchen, filtern oder sortieren möchte. Eine Liste mit Freunden oder eine automatische Texteingabe könnte bei jedem Tastenanschlag gefiltert werden, was eine deutlich schnellere Nutzererfahrung ermöglicht.

Tipp 4: JavaScript-Verbesserungen bringen erhebliche Leistungsvorteile

Dem Array-Prototyp wurden in JavaScript 1.6 viele zusätzliche Methoden hinzugefügt. Diese sind in den meisten Browsern verfügbar, mit Ausnahme von IE. Beispiel:

// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]

// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
  var linksList = document.querySelector('#links');
  var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
  linksList.innerHTML +=  newLink;
});


// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
  return number < 2;
});
// [1.618]


// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
  localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});

In den meisten Fällen erzielen Sie mit diesen nativen Methoden deutlich höhere Geschwindigkeiten als für eine Schleife, wie z. B. for (var i = 0, len = arr.length; i &lt; len; i++). Das native JSON-Parsing (über JSON.parse()) ersetzt die json2.js-Datei, die wir schon länger verwenden. Natives JSON ist viel schneller und sicherer als die Verwendung eines externen Skripts. Es ist bereits in IE8, Opera 10.50, Firefox 3.5, Safari 4.0.3 und Chrome enthalten. Das native String.trim ist ein weiteres gutes Beispiel dafür, dass es nicht nur schneller als die Langhand-JS-Äquivalente, sondern auch möglicherweise genauer ist. Keines dieser JavaScript-Add-ons ist technisch gesehen HTML5, doch sie fallen unter die Technologien, die erst seit Kurzem zur Verfügung stehen.

Tipp 5: Cache-Manifest für Live-Websites verwenden, nicht nur für Offline-Apps

Vor zwei Jahren hat WordPress mit Google Gears eine Funktion namens Wordpress Turbo hinzugefügt. Im Grunde wurden viele der im Admin-Bereich verwendeten Ressourcen lokal im Cache gespeichert, wodurch der Dateizugriff beschleunigt wurde. Dieses Verhalten lässt sich mit dem ApplicationCache von HTML5 und dem cache.manifest reproduzieren. Der Anwendungscache hat einen geringfügigen Vorteil gegenüber dem Festlegen von Expires-Headern. Da Sie eine deklarative Datei erstellen, in der die statischen Ressourcen angegeben werden, die im Cache gespeichert werden können, können Browser diese stark optimieren und sie vielleicht sogar vorab im Cache speichern. Betrachten Sie die Grundstruktur Ihrer Website als Vorlage. Sie haben Daten, die sich ändern können, aber der HTML-Code um sie herum ist in der Regel ziemlich einheitlich. Mit dem App-Cache können Sie Ihren HTML-Code als eine Reihe von reinen Vorlagen behandeln, das Markup über „cache.manifest“ im Cache speichern und dann JSON über die Verbindung senden, um den Inhalt zu aktualisieren. Dieses Modell ähnelt sehr derjenigen einer nativen Nachrichten-App für iPhone oder Android.

Tipp 6: Hardwarebeschleunigung aktivieren, um die visuelle Darstellung zu verbessern

In führenden Browsern kann für viele visuelle Vorgänge eine GPU-Beschleunigung genutzt werden, was hochdynamische visuelle Vorgänge reibungsloser gestalten kann. Für Firefox Minefield und IE9 wurde eine Hardwarebeschleunigung angekündigt. Safari hat in Version 5 eine Hardwarebeschleunigung hinzugefügt. Diese Funktion war bereits viel früher in Mobile Safari verfügbar. In Chromium wurden 3D-Transformationen und Hardwarebeschleunigung neu hinzugefügt. Die anderen beiden Plattformen werden demnächst verfügbar sein.

Die GPU-Beschleunigung wird nur unter relativ eingeschränkten Bedingungen aktiviert. Am häufigsten werden jedoch 3D-Transformationen und animierte Deckkraft verwendet. Die Aktivierung dieser Funktion ist etwas komplizierter, aber unaufdringlich:

.hwaccel {  -webkit-transform: translateZ(0); }

Garantieren Sie jedoch nicht. Wenn die Hardwarebeschleunigung unterstützt und aktiviert ist, funktionieren animierte Übersetzungen, Drehung, Skalierung und Deckkraft beim Erstellen von GPUs definitiv besser. Sie haben den Vorteil, dass sie direkt auf der GPU verarbeitet werden, und erfordern kein erneutes Zeichnen des Ebeneninhalts. Alle Properties, die sich auf das Layout der Seite auswirken, sind jedoch weiterhin relativ langsam.

Tipp 7: Bei CPU-intensiven Vorgängen liefern Web Worker

Web Worker haben zwei wesentliche Vorteile: 1) Sie sind schnell. 2) Während sie deine Aufgaben erledigen, bleibt der Browser dagegen reagiert. Sehen Sie sich die HTML5-Präsentation für Worker in Aktion an. Einsatzmöglichkeiten für Web Worker:

  • Textformatierung eines langen Dokuments
  • Syntaxhervorhebung
  • Bildverarbeitung
  • Bildsynthese
  • Große Arrays verarbeiten

Tipp 8: Attribute und Eingabetypen in HTML5-Formularen

HTML5 bietet eine neue Reihe von Eingabetypen und aktualisiert unsere Gruppe von text, password und file mit search, tel, url, email, datetime, date, month, week, time, datetime-local, number, range und color. Diese werden von unterschiedlichen Browsern unterstützt, wobei derzeit die meisten von Opera implementiert werden. Mithilfe der Funktionserkennung können Sie feststellen, ob der Browser native Unterstützung bietet und eine Benutzeroberfläche wie eine Datums- oder Farbauswahl bietet. Falls nicht, können Sie weiterhin die JS-Widgets für diese gängigen Aufgaben verwenden. Zusätzlich zu den Typen wurden einige nützliche Funktionen zu unseren normalen Eingabefeldern hinzugefügt. Die Eingabe-placeholder enthält Standardtext, der gelöscht wird, wenn Sie darauf klicken, und autofocus hebt das Caret-Zeichen beim Seitenaufbau hervor, sodass Sie sofort mit dem Feld interagieren können. Auch die Eingabevalidierung ist ein weiterer Bestandteil von HTML5. Wenn Sie das Attribut required hinzufügen, wird das Formular erst gesendet, wenn dieses Feld ausgefüllt ist. Mit dem Attribut pattern können Sie außerdem einen benutzerdefinierten regulären Ausdruck für die zu testende Eingabe angeben, wobei ungültige Werte das Senden von Formularen verhindern. Durch diese deklarative Syntax wird nicht nur die Lesbarkeit der Quelle erheblich verbessert, sondern es wird auch der erforderliche JavaScript-Aufwand reduziert. Auch hier können Sie die Funktionserkennung verwenden, um eine Fallback-Lösung bereitzustellen, wenn diese keine native Unterstützung bietet. Wenn Sie die nativen Widgets hier verwenden, müssen Sie nicht den umfangreichen JavaScript- und CSS-Code senden, der zum Abrufen dieser Widgets erforderlich ist. Dadurch wird der Seitenaufbau beschleunigt und die Reaktionsfähigkeit der Widgets verbessert. Einige dieser Eingabeoptimierungen können Sie in der HTML5-Präsentation ausprobieren.

Tipp 9: CSS3-Effekte verwenden, anstatt zu viele Bild-Sprites anzufordern

CSS3 bietet viele neue Gestaltungsmöglichkeiten, die die Verwendung von Bildern zur korrekten Darstellung des visuellen Designs ersetzen. Ein 2K-Bild durch 100 Byte CSS zu ersetzen, ist ein großer Gewinn. Außerdem haben Sie eine weitere HTTP-Anfrage entfernt. Hier einige der Properties, mit denen Sie sich vertraut machen sollten:

  • Lineare und radiale Farbverläufe
  • Rahmenradius für abgerundete Ecken
  • Box-shadow für Schlagschatten und Schein
  • RGBA für Alpha-Deckkraft
  • Transformationen für Rotation
  • CSS-Masken

Sie können beispielsweise sehr ausgefeilte Schaltflächen über Farbverläufe erstellen und viele andere Effekte ohne Bilder replizieren. Die meisten Browser werden von vielen Browsern unterstützt und Sie können eine Bibliothek wie Modernizr verwenden, um Browser abzufangen, die die Funktionen nicht unterstützen, und so in einem Fallback-Fall Bilder verwenden zu können.

Tipp 10: WebSockets für eine schnellere Bereitstellung mit weniger Bandbreite als XHR

WebSockets wurde als Reaktion auf die wachsende Beliebtheit von Comet entwickelt. Die Verwendung von WebSockets gegenüber dem Modell „Komet über XHR“ bietet jetzt tatsächlich Vorteile.

WebSockets weist sehr leichtes Framing auf, sodass die von ihm verbrauchte Bandbreite oft geringer ist als die von XHR. Einige Berichte zeigen eine Reduzierung der über die Leitung gesendeten Byte um 35 %. Außerdem ist bei einem größeren Volumen der Leistungsunterschied bei der Nachrichtenzustellung deutlicher erkennbar. XHR wurde in diesem Test mit einer Gesamtzeit von 3.500% länger erfasst als WebSockets. Zuletzt hat Ericcson Labs die Leistung von WebSockets untersucht und festgestellt, dass die Ping-Zeiten über HTTP aufgrund größerer Verarbeitungsanforderungen 3- bis 5-mal länger waren als über WebSockets. Sie kamen zu dem Schluss, dass das WebSocket-Protokoll deutlich besser für Echtzeitanwendungen geeignet ist.

Weitere Ressourcen

Für Mess- und Leistungsempfehlungen sollten Sie auf jeden Fall die Firefox-Erweiterungen Page Speed und YSlow verwenden. Darüber hinaus bieten Speed Tracer für Chrome und DynaTrace Ajax für IE eine detailliertere Protokollierung der Analyse.