speeding up webapps

Vorbetrachtung

Einige Dinge, die wir hier besprechen, sind in aller Ausführlichkeit auch in DOLOTO beschrieben. DOLOTO geht da schon ziemlich zur Sache, wir werden es hier aber erstmal etwas ruhiger angehen lassen. Geschwindigkeitskiller beim Seitenaufbau sind vor allem:

  • viel Javascript
  • Viele Dateien
  • große Dateien

Diese Killer zu beseitigen ist in manchen Fällen schwer, in anderen ganz leicht. Warum steht die Dateigröße an letzter Stelle? In Zeiten von DSL spielt es keine große Rolle, ob eine Seite 50KB oder 500KB an Daten zwischen Server und Client hin und her transportiert. Viel wichtiger ist hier, dass die derzeitig aktuellen Browser nur zwei Requests gleichzeitig zu einer Domain öffnen können, also auch nur zwei Dateien gleichzeitig anfordern können – und dass mehr Requests auch mehr Overhead bedeuten. Würden wir es also schaffen, all unsere Daten in zwei gleich große Dateien zu packen, würden dieser initiale Load deutlich schneller abgeschlossen. Eine andere Möglichkeit wäre es, mit mehreren Quellen zu arbeiten. Schauen wir uns das einfach mal bei google an. Die Google-Map beinhaltet sehr viele Bilder, die der Client aber von mehreren zufällig bestimmten Domains herunterlädt. Die Kartenkacheln kommen von:

  • kh1.google.com
  • kh0.google.com
  • kh2.google.com und
  • kh3.google.com, sowie von
  • mt0.google.com
  • mt1.google.com
  • mt2.google.com und
  • mt3.google.com.

Bei zwei Requests gleichzeitig kann unser Client also von google 16 Bilder gleichzeitig anfordern und herunterladen, während er von einer einzelnen Domain nur 2 Bilder holt. Dabei ist es völlig egal, ob es sich hier um verschiedene Rechner, Cluster oder Farmen handelt. Technisch könnten alle google-Bilder auf einem Rechner in einem Ordner liegen. Würden wir also eine Domain „img.domain.de“ haben, von der wir alle Content-Bilder ziehen, alle Background-Bilder lägen weiterhin auf http://www.domain.de, könnten die Ladezeit für Bilder halbieren. Viel schlimmer, als eine große Datenmenge ist es also, viele Dateien von einer Domain aus zu übertragen. Eine wichtige Möglichkeit, die Anzahl der Datein zu verringern, sind zusätzlich zu Multi-Domain-Downloads css-Sprites. Und warum steht nun das Javascript an erster Stelle? Obwohl wir nun durch viele kleine und große Speedups, duch schlaues Chaching und vielleicht sogar durch css-Sprites unseren html-Content wahnsinnig schnell zum Client übertragen können, wird der Browser erst anfangen, das html zu rendern, wenn er die letzte Zeile Javascriptcode interpretiert hat. Hier ist nichteinmal entscheidend, wieviele Funktionsaufrufe initial gestartet werden – er muss einfach das gesamte Script danach durchsuchen, ob noch irgendwo ein Funktionsaufruf, eine globale Variable, oder einfach eine sofort auszuführende Anweisung versteckt ist. Komplexe Web2.0-Portale, die effektreich relativ viele Aufgaben dem Client überlassen, haben einfach auch mit großen Mengen an Javascript zu kämpfen Angenommen, wir laden wir beim ersten Start des Portals über 1MB an Daten in 193 Dateien auf den Client. Unsere Javascripte sind mehrere 10.000 Zeilen lang. Der Client wartet also alle 193 Dateien ab, interpretiert danach zehntausede Zeilen Javascript – und fängt dann an zu rendern.

cheap Speedup

Ohne jetzt anzufangen, mehrere Domains anzulegen, Javascripte zu splitten oder css-Sprites zu generieren, können wir schon Einiges an Geschwindigkeit herausholen.

Simpler Javascript-Trick

Google selbst empfiehlt, awinw APIs mit dem AJAX-Loader zu holen:

<script type="text/javascript" src="http://www.google.com/jsapi?key=ABCDEFG"></script>

Was ist der Unterschied? Beim Seitenaufbau lädt der User nicht mehr die gesamte komplexe maps-API, sondern nur ein kleines Script, dass dem Browser ermöglicht, via AJAX die API nachzuladen. Das kleine Script ist statt der 4kB der API nur um 1KB kleiner – Datenmenge spielt nur eine untergeordnete Rolle – enthält aber ungepacktes Javascript, das vom Browser rasch interpretiert ist. Der Browser wird also nur mit wenigen Zeilen Javascript aufgehalten und kann sofort beginnen, die Seite fertig zu rendern. Der Browser kann im Hintergrund auch schon die komplette API herunterladen, (die Datenmenge spielt keine Rolle), er interpretiert aber erst wenn das Event „DOMContentLoaded“ gefeuert wird, oder nach einem timeout von 10ms nachdem der Browser fertig ist, die Seite zu rendern, die maps-API.

besserer Javascript Trick

Wie google auch, könnte jedes Portal einen Großteil seiner Scripte einfach dynamisch nachladen.

Verringerung der Datenmenge

Das letzte bisschen Geschwindigkeit ließe sich über die Komprimierung der Datenmenge herausholen. Für Javascript gibt es mehrere Möglichkeiten, die sich auf zwei Klassen vereinfachen lassen.

  • „shrinken“ durch Kürzen der Variablennamen, entfernen von Kommentaren und Whitespaces
  • packen, durch echtes Komprimieren des Scripts

Gepackte Files müssen auf dem Client erst wieder ausgepackt werden, geshrinkte Files lassen sich gleich ausführen. Da ein gepacktes und ein geshrinktes File gleichgroß sind, wenn sie serverseitig durch gzip komprimiert wurden, sollte man eher shrinken. Literatur (http://kevin.vanzonneveld.net/techblog/article/better_performance_with_mod_deflate/)

Fazit

Oberste Priorität sollte daher haben, die Anzahl der heruntergeladenen Dateien zu reduzieren, an zweiter Stelle steht ein AJAX-Loader, ein schöner Trick und darum an dritter Stelle sind mehrere Daten-Domains – wegen der Suchmaschinenoptimierung darf hier allerdings nicht zufällig von mehreren Domains Inhalt gezogen werden – sondern jedes Bild muss seine feste Domain haben und darf nie von woanders kommen.

Advertisements

Ein Kommentar zu “speeding up webapps

  1. […] für Teckies Im vorangegangen Speedup-Artikel bin ich ja relativ theoretisch auf kleine Performance-Gewinne eingegangen, wobei das Setzen auf […]

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s