Facebook
Twitter
Google+
Kommentare
9

Website Performance

Nachdem dieser Artikel doch ein wenig länger geworden ist als ich ursprünglich geplant hatte, möchte ich das Thema mit einer kleinen Einleitung beginnen.

Die Webseite ist langsam, was nun?

Oftmals vergessen Entwickler, dass die Entwicklung auf einem lokalen System andere Voraussetzungen darstellen, als später auf dem Echtsystem gegeben sind und am Ende verwundert sind weshalb die Applikation plötzlich nicht mehr schnell ist.

Von was reden die, die Webseite ist doch schnell!

Das mag wohl auch zutreffen, wenn man die Webseite aus dem selben Netz aufruft in welchem sich der Webserver mit der Applikation befindet 🙂 und nicht von der Zweigstelle in Malta, die sowieso grundsätzlich eine miese Internetanbindung zum Festland haben.

Ich bin sicher nicht schuld, dass die Webseite langsam ist!

Ich bin der festen Überzeugung, das an Performance Problemen zu 90% die ProgrammiererInnen schuld sind. Das Hauptargument, das ich bislang von ProgrammiererInnen bzgl. Performance Problemen gehört habe ist: „Wir haben eine schnelle Internetanbindung, die Webseite muss schnell laufen. Es ist bestimmt das Netzwerk schuld.“ Ich weiß, dass diese Aussagen in der Praxis zu 90% von Netzwerktechnikspezialisten widerlegt werden.

Ein einfaches Beispiel zum Verständnis:

Ein Bäcker liefert Wurstsemmeln aus. Die Anbindung zu seinen Kunden sind 10-spurige Autobahnen, die superschnelle Internetanbindung an unseren Server bzw. die Anbindung vom Kunden zum Lieferanten. Er muss jedoch, um das mit einem HTTP Request zu vergleichen, zuerst von seinem Standort Wien zum Kunden nach Graz fahren, um zu erfahren wie viele Semmeln mit welcher Wurst er eigentlich haben möchte, um danach wieder zu seinem Betrieb nach Wien zu fahren, um die Semmeln fertig zu machen und danach zum Kunden zu bringen. Dort angekommen sagt ihm der Kunde er hätte gerne noch Mayonaise zu seinen Semmeln. Der liebe Bäcker düst wieder auf der 10-spurigen Autobahn retour, um die Mayonaise aus Wien zu holen und bringt sie anschließend dem Kunden nach Graz usw. Ihr seht also, die 10-spurige Autobahn bringt uns genau nichts, um einen Kunden schneller befriedigen zu können und ähnlich ist es mit Webseiten. Klar, man kann durch die Anbindung viele Requests schneller entgegen nehmen, aber der Weg bleibt immer der gleiche.

Dieser Artikel beruht auf eigenen Erfahrungen und auf dem Buch von Steve Souders „High Performance Web Sites“.

HTTP Requests minimieren

Eine Webseite benötigt lediglich 5% der Zeit um HTML Code zu laden, die restlichen 95% werden alle anderen Elemente geladen. Schaut euch eure Webseite einmal mit einem Textbrowser wie Lynx an und vergleicht die Ladezeiten, ihr werdet einen großen Unterschied bemerken. Ihr könnt außerdem das Tool httpwatch (es gibt, so weit ich weiß auch eine freie Version; leider nicht für Mac) verwenden, um zu sehen was beim Laden eurer Webseite genau passiert und wie lange es dauert bis alle Elemente geladen wurden.

HTTP Requests kann man z.B. über Verwendung von Image Maps oder CSS Sprites (einen Bildausschnitt über Koordinaten anzeigen) minimieren.

mod_expires: Header manipulieren

Bei jedem Seitenaufruf wird ein HTTP Request dazu verschleudert, dem Browser mitzuteilen wie lange gewisse Objekte gültig sind. Das ist grundsätzlich aber nicht notwendig, da man die Gültigkeitsdauer einzelner Elemente mit dem Apache Modul mod_expires festlegen kann. Sinnvoll ist es Elementen, die sich selten ändern (z.B. Bilder des Layouts) einen weit in der Zukunft liegenden Expiredate zu geben, damit diese automatisch gechacht werden und der Browser nicht auf jeder Seite nachfragt wie lange z.B. Bilder gültig sind.

mod_deflate: Gzip Compression

Mit dem Apache Modul mod_deflate ist es möglich Content an den Client komprimiert zu senden. Dieses Modul verwendet das Gzip Kompressionsformat. Das Gzip Format ist frei und wird von den meisten Browsern unterstützt.
Was kann man komprimieren? Im Grunde alles: HTML, Scripts und Stylesheets. PDF Dateien sollte man nicht komprimieren, da diese schon komprimiert sind. Durchschnittlich reduziert man unter Verwendung von Komprimierungsmethoden die Seitengröße ca. um 70 Prozent und spart daher Bandbreite.

Stylesheets oben und JavaScripts unten

Eine Webseite wird stufenweise bzw. blockweise gerendert und von Stylesheets unterbrochen. Daher sollten Stylesheets immer im HEAD Bereich unter Verwendung des LINK-Tag eingebunden werden. @import sollte nicht verwendet werden, da @import Dateien erst am Ende einer Seite geladen werden und die externe Variante um ca. 30-50 Prozent schneller ist. Der Grund dafür ist, dass das externe Einbinden von Dateien zwar weitere HTTP Requests verursacht, aber dafür parallel heruntergeladen werden und sich die Dateien danach schon im Cache des Benutzers befinden.
JavaScript sollte man immer nur am Ende der Seite einbinden, denn auch durch JS wird das blockweise Rendering unterbrochen. Ein weiteres Problem ist, dass JS paralle Downloads des Browsers blockiert. Mehr dazu unter „Parallele Downloads“. Außerdem sollte man den JS Code minimieren. Dazu gibt es Tools wie z.B. Dojo Compressor, die JS Code um bis zu 40 Prozent minimieren können.

Parallele Downloads

Wenn Skripte mitten in der Seite platziert werden, wird das gesamte Rendering des nachfolgenden Inhalts gestoppt. Das bedeutet es wird gewartet bis das Skript fertig geladen wurde bis andere Elemente wieder parallel heruntergeladen werden können.

Browser laden grundsätzlich parallel die Elemente einer Webseite herunter, das ist auf HTTP/1.1 zurück zu führen wo definiert wurde, dass pro Host zwei Komponenten parallel herunter geladen werden. Soweit ich weiß hält sich der Internet Explorer nach wie vor an diese Definition. Firefox hingegen lädt standardmäßig acht Komponenten parallel herunter, das ist mit ein Grund weshalb Firefox einfach schneller ist. Die diesbzgl. Standard Firefox Settings kann man sich unter network.http.max-persistent-connections-per-server ansehen.

Was bringt uns dieses Wissen nun?

Wir können unsere Besucher nicht auffordern, dass sie ihre Browsereinstellungen ändern sollen, damit die Seite schneller geladen wird. Das ist mal klar.
Wir können DNS Aliases, CNAMEs, anlegen, um unsere Komponenten auf verschiedenen Hostnamen zu verteilen bzw. zu splitten. Es werden also nun mindestens zwei Elemente pro Host gleichzeitig geladen. JavaScript würde jedoch nach wie vor jedes Laden anderer Elemente blockieren, egal wie viele Hosts im Spiel sind! Daher sollte man JavaScript immer am Ende einer Seite einbinden.

DNS Lookups

Dieses Kapitel stellt auf den ersten Blick wohl einen Widerspruch zu dem vorigen dar, da ich hier darauf hinweisen möchte DNS Lookups so niedrig als möglich zu halten, da diese Performance seitens der Browser kosten.
Browser halten sich grundsätzlich nicht ans Betriebssystem bzgl. der time-to-live TTL, die sie vom Host zurück bekommen. Jeder Browser hat seinen eigenen DNS Cache. Beim erstmaligen Aufruf einer Seite fragt der Browser beim Betriebssystem nach, um sich die Hostadresse zu holen, um danach mit dem eigenen DNS Cache weiter zu arbeiten. Das hat bei Firefox z.B. zur Folge, dass bei Vielsurfern viele DNS Lookups erfolgen und die Seite daher für den Benutzer langsamer wird. Man kann die Einstellungen unter network.dnsCacheExpiration einsehen.
Wenn der Webserver keep-alive unterstützt werden die DNS Lookups, die der Benutzer beim Surfen auf deiner Webseite verursacht, minimiert.
Steve Souders sagt, dass man minimal zwei und maximal vier Hosts verwenden sollte, um ein Mittelmaß zwischen DNS Lookups und der Möglichkeit von parallelen Downloads zu erzielen.

Über den Autor

Ewi

Als ich die Oberstufe mit 17 abgebrochen habe und als Sekretärin, ähm Office Managerin, zu arbeiten begann, stellte ich sehr schnell fest, dass ich keine Aktenhüllen für irgendwelche hochnäsigen Professoren schlichten möchte und stellte mir die Frage "Was willst du eigentlich mal machen?". Ohne mir lange überlegt zu haben, ob mich die Materie überhaupt interessieren wird, eher vom Gedanken geleitet „irgendeine“ eine Schule abzuschließen und vom damaligen EDV-Boom beeinflusst, habe ich mich für eine der renommiertesten EDV Schulen Österreichs, der HTL Spengergasse Abendschule (ja, tagsüber arbeiten und abends Schule) entschieden, die ich 1999 begonnen und mittlerweile seit einigen Jahren abgeschlossen habe. Ich programmiere also seit Ende 1999 und bin mittlerweile selbstständig (knitwork).
Kommentare

9 Comments

  1. Die Firefox-Erweiterung „YSlow“ (benötigt „Firebug“) zeigt für eine Webseite die Ladezeiten der einzelnen Komponenten an und gibt auch spezifische Ratschläge.

    Reply
  2. Und dann gibt es noch „PHPSpeedy“, zu dem ich grade auch noch etwas schreibe. Leider werden die auf der Platte gecachten Dateien ständig als „Malicious JavaScript“ erkannt …

    Bezüglich des Artikels: Etwas mehr belege fände ich nicht schlecht. Vor allem, wenn du schon Souder zitiert, dann verlink ihn wenigstens. Das macht die Blogossphäre immerhin aus 😉

    Reply
  3. @unset: Ich weiß, aber ich muss die Leute ja hier verteidigen, die mir helfen hier was zu schreiben 😉 Obwohl ich mir bei Evelyne sehr sehr sicher bin, dass sie das auch selbst kann. Ist also nicht böse gemeint.

    Reply
  4. danke Nils für deine aktive Verteidigung deiner Blogger 🙂

    @unset: du hast Recht, keine Frage, aber ich muss ganz ehrlich gestehen, dass ich zu faul dazu war, zumal ich diesen Beitrag im Neo geschrieben habe und mir das dann zu mühsam ist/war. Ich werde mich das nächste mal bemühen, dass ich Links zu Authoren, Software, Referenzen, etc. angebe.

    Reply
  5. Kann es durch die Aktivierung der gzip-Compression zu irgendwelchen Problemen kommen? Und wie kann ich feststellen, ob diese aktiviert ist, wenn ich nur einen ganz normalen Webspace habe?

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen