Text_2
Facebook
Twitter
Google+
Kommentare
11

Was alles wichtiger als ein Content Delivery Network ist

Vorab erst einmal eine Definition: Ein Content Delivery Network (kurz: CDN) ist ein Netz von mehreren, über die ganze Welt verteilten Server, die Inhalte im Internet ausliefern. Bekannte Anbieter sind etwa Akamai oder die Amazon Web Services. Besondere Eigenschaften eines CDN sind vor allem seine hohe Geschwindigkeit mit der Inhalte ausgeliefert werden und die hohe Verfügbarkeit, mit der Inhalte bereitgestellt werden.

Ein Allheilmittel?

Nach dieser kurzen Definition mag sich ein CDN wie ein Allheilmittel anhören – was es aber natürlich nicht ist! Ein CDN sollte erst eingesetzt werden, wenn alle anderen Punkte, die bei der Auslieferung einer Website optimiert werden können, ausgereizt sind. Wird ein CDN schon zu Beginn eingesetzt, fehlt das Gespür dafür an welchen Stellen noch weiter optimiert werden sollte.

Der Beitrag soll im Folgenden einige Inspirationen geben, wo genau angesetzt werden kann, um die Performance einer Website während der Übertragung zu beschleunigen.

Grundsätzlich sollte die eigene Testumgebung auch die ältesten und langsamsten Browser beinhalten. Hier helfen Tools, die langsame Internetverbindungen wie GPRS oder 3G simulieren. Für modernere Browser und höhere Geschwindigkeiten können dann Bonbons hinzugefügt werden. Wer den IE8 unterstützen muss, sollte auch gleich im IE8 entwickeln.

Inhalte und keine Ladebalken ausliefern.

Niemand möchte Ladebalken sehen – vor allen Dingen nicht mobil – denn jeder Millimeter des Ladebalkens frisst das eigene, viel zu geringe, Datenvolumen langsam auf. Besser ist es, direkt von Anfang an konkrete Inhalte zu liefern. Allerdings auch wirklich nur solche, die dann auch angezeigt werden.

Sprites

Sprites sind grundsätzlich immer dann suboptimal, wenn es um die Performance der Übertragung geht. Wenn alle Grafikelemente der Website schon beim Laden übertragen werden, bleiben eine Menge Nutzer auf der Strecke, die mit dem Smartphone unterwegs sind und, beispielsweise in der U-Bahn, nicht lange warten wollen.

Javascript Frameworks

Auch der Einsatz eines Javascript Frameworks sollte kritisch hinterfragt werden. Wird durch das Framework mehr Code gespart als das Framework an eigener Größe besitzt? In vielen Projekten wird jQuery nur wegen des Selektors integriert. Langfristig ergibt es tatsächlich sehr viel mehr Sinn, stattdessen einen eigenen kleinen Werkzeugkasten in Javascript anzulegen und daraus nur jeweils die Funktionen in den Code zu übernehmen, die auch wirklich benötigt werden.

CSS

Bei CSS gilt das Gleiche. Wenn Tools wie compass oder SASS verwendet werden, solltet ihr unbedingt darauf achten, dass keine unnötigen Kommentare o.ä. erzeugt werden. Hier macht es außerdem Sinn, sich selbst ein kleines responsive Grid zu schreiben statt auf Bootstrap zurückzugreifen.

Photos

Die Inhalte, die nach diesen Schritten noch übrig bleiben und wirklich initial benötigt werden, müssen nun absolut perfekt optimiert sein. Ein guter Trick für Photos ist, diese doppelt so groß, aber mit höherer Kompression auszuliefern.  Das hat Vor- und Nachteile – bringt aber vor allem bei guter Qualität eine geringere Dateigröße mit sich und sieht gleichzeitig, aufgrund der höheren Pixelanzahl auf Retina, sehr viel besser aus.

Gleichzeitige Anfragen reduzieren und so viel wie möglich cachen.

Vor allem mobil möchte man so wenig (gleichzeitige) Verbindungen wie möglich, denn mobile Internetverbindungen haben von Natur aus eine hohe Latenz. Zusätzlich gehen im Äther auch gerne einmal Bytes verloren, welche dann mit weiterer Latenz wieder angefordert werden müssen. Durch diesen Overhead wird die Latenz immer schlimmer.

Base64 kodierte Icons

Sprites sind, wie oben bereits erwähnt, sehr problematisch da hier eine Menge grafisches Material geladen wird, das möglicherweise noch gar nicht benötigt wird. Gleichzeitig aber haben Sprites den Vorteil, dass nur eine einzige Bild-Datei übertragen wird. Ein guter Kompromiss ergibt sich dann, wenn vorhandene Icons direkt Base64 enkodiert in die CSS Datei eingetragen werden, denn die CSS Datei muss ohnehin übertragen werden – und die Icons sind direkt da, wenn die entsprechende CSS Direktive umgesetzt wird.

Wichtig ist auch hier, dass kein komplettes Iconset in die CSS Datei geschrieben wird, sondern lediglich die benötigte Elemente – meist lediglich eine Handvoll. So wird auf eine riesige Sprite-Datei verzichtet und trotzdem entstehen keine zahlreichen kleinen Verbindungen für viele kleine Icons.

Konkatenierte Assets

Zum Entwickeln macht es vielleicht der Übersichtlichkeit halber Sinn, CSS- oder Javascript-Dateien aufzuteilen. Diese übrigen Assets, sollten aber vor dem Ausliefern nochmals mit einem weiteren Tool wie beispielsweise Grunt komprimiert und jeweils aneinandergehangen werden.

Serverseitig

Nach Möglichkeit empfielt es sich, aufgrund der Anzahl der Verbindungen, auf Cookies zu verzichten. Worauf aber auf keinen Fall verzichtet werden sollte ist GZip.

Wichtig bei statischen Inhalten ist, diese mit einem “public” Cache Header zu versehen. Das “expiry date” sollte außerdem möglichst weit in der Zukunft liegen.

Was außerdem für gutes Caching wichtig ist: Versioniert eure statischen Inhalte in Ordnern und nicht via Query-String. Bei manchen Proxy Servern spült es andernfalls die Datei nicht durch – und wir sind ja auf Caching angewiesen!

Das Optimale Setup

Heruntergebrochen sind zum Initialen Laden einer Website nur ganz wenige Elemente nötig – und es sollten auch nur diese ausgeliefert werden.

Der Client benötigt:

  • Ein HTML Gerüst
  • Eine einzige CSS Datei (Möglichst minimal, aber inkl. Icons)
  • Eine einzige Javascript Datei (Kein Framework)
  • Immer nur die Bilder, die angezeigt werden (Bestmöglichst komprimiert)

Serverseitige Checklist:

  • Auf Cookies verzichten
  • Gzip aktivieren
  • “public” Cache Header
  • Cache “expiry date” in ferner Zuknft

Und dann – ja, dann kann man ein CDN darauf setzen und es geht richtig ab!

Fazit

Die meisten dieser Verbesserungen sind vermutlich nicht, oder nur schwer, im Büroalltag mit großem Bildschirm und angemessener Internetleitung spürbar. Viele dieser Ansätze sind Handarbeit und erfordern wieder etwas mehr Anstrengung, als wir es von modernen Frameworks gewohnt sind. Es ist gewissermaßen eine kleine Rückkehr zur Basis – aber wenn erst einmal die mühselige Handwerkskunst vollendet ist, sorgt ein CDN dafür dass eure Arbeit auf der ganzen Welt hochverfügbar wertgeschätzt werden kann.

 

Über den Autor

Klaus Breyer

Klaus Breyer Gründer und Geschäftsführer der buddybrand GmbH, dort verantwortlich für Technologien und Prozesse. Als Social Media Agentur entwickelt buddybrand digitale Marken- und Kommunikationsstrategien, kreiert Inhalte und Kampagnen, und schafft internes Verständnis und Strukturen für internationale Markenunternehmen wie ŠKODA, Heineken, airberlin oder Storck. Ist in der deutschen Start-up- und Technologie-Szene gut vernetzt und auf Konferenzen gerne als Speaker. Stärke: Technische Inhalte einfach und anschaulich zu erklären. Bloggt über diese und ähnliche Themen auch auf klaus-breyer.de.
Kommentare

11 Comments

  1. Wir hatten damals begonnen auch ein CDN zu setzen, weil mir Probleme mit der Bandbreite hatten. Wir hosten im „Keller“ und haben nur eine 3 GBit Anbindung. Bei einer SternTV-Sendung kann dann mal die Leitung platt sein.

    Ansonsten vielen Dank noch für den Artikel.

    Reply
    • Das Google Maps Beispiel ist ja ein etwas anderer Anwendungsfall. Da geht es ja vor allem um die Bilder, die nachgeladen werden und nicht um die Auslieferung der Anwendungslogik. Dort macht es natürlich total Sinn, genau die Bilder zu laden, die angezeigt werden. Damit steht es ja auch nicht im Widerspruch. 🙂

      Reply
      • Dann muss ich das anders formulieren:

        > Besser ist es, direkt von Anfang an konkrete Inhalte zu liefern.
        > Allerdings auch wirklich nur solche, die dann auch angezeigt werden.

        Ich finde es total nervig wenn man heute auf eine „moderne“ Internetseite kommt, scrollt, und der Browser dann erst einmal wieder Inhalte nachladen muss.

        Das ist in meinen Augen so ein ähnlicher Hype wie „Parallax“ beim Design (siehe dazu: http://praegnanz.de/weblog/zur-hoelle-mit-parallax). Klingt toll, ich habe einen Grund meine JS Library dauerhaft einzubinden… aber eigentlich total doof.

        Wenn man wirklich auf „Lazy-Loading“ angewiesen ist, dann ist das ein Anzeichen dafür, dass die Seite überladen ist, sprich zuviel Inhahlt bietet. Hier sollte man ansetzen und nicht den unnötigen Inhalt verzögert laden lassen.

        Denn neben der Usability (überladene Seiten überfordern den Nutzer) gibt es auch technische Gründe: Die initiale Ladezeit mag zwar gering sein. Aber die ganze JS Logik mit den tausend registrierten Events usw. macht die Seite am Endgerät langsam. Gerade dann, wenn der Anwender wirklich einmal die Seite von oben bis unten gelesen hat – dann frisst dieser eine Tab quasi den gesamten Gerätespeicher (schließlich ist ja nun jedes Element geladen). Beispiel http://www.rp-online.de/

        > Sprites sind grundsätzlich immer dann suboptimal, wenn es um die
        > Performance der Übertragung geht. Wenn alle Grafikelemente der Website
        > schon beim Laden übertragen werden, bleiben eine Menge Nutzer auf der
        > Strecke, die mit dem Smartphone unterwegs sind und, beispielsweise in
        > der U-Bahn, nicht lange warten wollen.

        Ich hoffe hier differenzierst du lediglich nicht genug. Das klingt für mich erst einmal so, als würdest du Sprites allgemein verteufeln.

        Könntest du evtl. mal ein konkretes Negativbeispiel benennen?

        Ansonsten bin ich der Meinung: Ein richtig gemachtes Sprite ist wichtig und braucht es. Eine Seite kann je nach Komplexität auch mehrere Sprites haben. So wie beim JS braucht es evtl. nicht immer alles… aber das Grunddesign in einem Sprite zusammenzufassen spart einiges.

        > Gleichzeitige Anfragen reduzieren und so viel wie möglich cachen.

        Hier sehe ich den primären Widerspruch zu den Empfehlungen von Google.

        Halten wir erst einmal fest, dass wir uns darauf geeinigt haben, nur das, was nötig ist, zu laden. Den Nutzer dabei auch nicht mit Content zu erschlagen.

        So wie ich deinen Text verstehe empfiehlst du bspw. so wenige Quellen (Hostnames) wie möglich zu verwenden. Genau das sieht Google (und ich) anders.

        Der IE und FF hatten vor 2-3j recht konservative Einstellungen bzgl. Verbindungen zum Webserver. Das konnte man zwar alles schon hochschrauben, aber standardmäßig wurde auf =16 Verbindungen gestartet (es gibt per Site und per Host Werte).
        Desto mehr Verbindungen, desto schneller sind in der Regel alle notwendigen Ressourcen geladen. Das funktioniert am besten, wenn die Daten auch noch über mehrere Hosts verteilt sind, weil so das „Per Host“-Limit umgangen wird.

        Insofern macht es schon Sinn wenn man http://www.example.org betreibt seine ganzen Bilder/Assets von !*.example.org zu beziehen. Wenn man mehr als 10 Ressourcen hat lohnt sich auch schon wieder die Unterteilung in cdn1.mynocookiedomain.com und cdn2.mynocookiedomain.com.

        Ich gebe dir Recht, dass es in der mobilen Welt anders aussieht. Verbindungsaufbau ist immer das teuerste (kennen wir hoffentlich auch von PHP: Wenn pro Request mehrere Verbindungen zum DB-Server ständig neu aufgebaut werden müssen, kostet das — hier kann ein Connection-Pool abhilfe leisten, da dann der ständige Verbindungsaufbau entfällt) und gerade bei Verbindungen mit hohen Latenzen sollte man diese minimieren. Da wären wir aber bei einer anderen Sache die ich wichtig finde:

        Den heutigen Ansatz mit Responsive Design usw. um mit einer Site alle Nutzungsszenarien abzudecken halte ich für falsch. Es ist nun einmal Fakt, dass verschiedene Endgeräte völlig anderen Content benötigen.

        – Wozu einem Smartphone mit <10" Display hochauflösende Grafiken senden?

        – Es ist toll mit einem HDPI-Gerät "einfache" Grafiken zu betrachten. Zerstört jedes ach so tolle Design.

        – Conditionals usw. sind ja toll. Nur ein mobiles Gerät wird ganz sicher *nie* seinen Bildschirm vergrößern können. Wozu also den ganzen Kram den das Gerät definitiv nie ausführen wird mitsenden?

        – Muss ich an nicht-Touch-fähige Geräte Touch-Code schicken und gar ausführen?

        Besser man macht sich den Aufwand und liefert wirklich 3 Versionen einer Internetseite:

        1) Optimiert für mobile Geräte

        2) Optimiert für Tablets

        3) Optimiert für Desktops

        Das ist erst einmal mehr Aufwand, ja. Aber wenn es um Optimierungen für den Endanwender geht dann kann ich nur auf diese Weise das optimale Ergebnis liefern (ganz wichtig: Der Endwender muss immer die Möglichkeit haben von der Mobile-Site auf die Desktop-Site ect. wechseln zu können und umgekehrt).

        Kommen wir zum zweiten Teil deines Satzes: Cache ist wichtig. Aber beim cachen muss man einiges beachten:

        – Header-Kram

        – Mobile Geräte haben einen begrenzten Speicher. Zu große Elemente cachen sie nicht. Auch cachen viele Plattformen pro Site nur eine begrenzte Anzahl an Elementen (gerade hier profitiert man dann wieder von der Trennung in mehrere Hosts).

        Im Idealfall dauert der erstmalige Aufruf also etwas, weil ein Sprite, die kombinierte JS Datei usw. geladen werden muss. Aber alle weiteren Aufrufe sind flott. Hier lohnt sich mal ein technischer Blick auf die MEGA Seite zu werfen. Die nutzt bspw. auch den lokalen HTML5 Store um Dinge auf dem Client zwischenzulagern. Damit umgeht man elegant die angesprochenen Caching-Limits mobiler Geräte. Außerdem kann man so die Verbindungszahl reduzieren, wenn von der Hauptseite eine Revision mitgeteilt wird und nur wenn diese nicht mit der Revision des lokalen Speichers übereinstimmt werden die Ressourcen nachgeholt. Das spart dann auch noch 304er.

        Ganz wichtig: Immer auch schauen welche Auswirkungen gewisse Optimierungen für den Browser haben. Wenn ich viele Bilder als Base64 mitliefere, hat das bspw. negative Auswirkungen auf den Memory-Footprint der Webseite im Browser. Dann habe ich zwar paar Requests gespart, dafür fühlt sich die Seite laagy an (und gerade in der Android-Welt gibt es schwache Geräte, wo der Effekt sich dann potenziert). Gleiches gilt auch für Sprites: Wenn das Sprite insgesamt zu breit/lang ist, dann frisst das Sprite zuviel RAM…
        Whitespace-Optimierung kann man auch übertreiben.

        Reply
  2. Naja ‚fehlendes Gespür‘.. wohl eher weniger, ein CDN nimmt in der Regel nicht die gesamte Optimierungsarbeit ab, maximal ein Teil davon. Wenn es das tut ist das ja auch nicht schlecht.
    Viel wichtiger finde ich stattdessen die Frage, ob ein CDN überhaupt sinnvoll ist. Das ist nämlich eher bei (größeren) internationalen Seiten der Fall. Als Deutscher Blogbetreiber, der überwiegend deutschen Traffic bekommt und daher sinnvollerweise in DE hostet, bringt es mir schließlich nix wenn ich meine Inhalte direkt aus 99 verschiedenen Ländern an die Besucher schicken kann, weil ich die gar nicht habe. Alle anderen Optimierungen kann man selbst vornehmen oder zur Not jemanden Beauftragen. Dementsprechend geht da also nicht unbedingt ‚richtig was ab‘ nur weil man ein CDN nutzt. Das hier aufgezählte ist in heutigen Webanwendungen eigentlich nur die Spitze vom Eisberg, über Caching in der Anwendung selbst kann man meist viel mehr rausholen. Im Optimalfall kann die komplette Seite über einen fronted caching-server gecached werden, dann kann man seine reine Ladezeit auf wenige hundert ms reduzieren. Wobei das natürlich stark von der jeweiligen Anwendung abhängt. Serverseitig kann gerade bei stärker frequentierten Seiten natürlich auch noch sehr viel gemacht werden. Alleine Datenbankoptimierung ist noch mal eine Wissenschaft für sich.

    Zusätzlich clientseitig zu optimieren ist natürlich trotzdem sinnvoll. Das eine schließt das andere ja nicht aus, im Gegenteil: So kann die Performance noch weiter verbessert werden. Die Erklärung zu Sprites ist aber Unsinn. Sprites sind nicht grundsätzlich suboptimal. Erst mal zwingt dich keiner, ALLE 999 Bilder deiner gesamten Seite in ein Sprite zu legen. Sprites kann man sinnvoll aufteilen, beispielsweise ein globales Sprite für Header + Footer und je eines für die seitenspezifischen Grafiken. Wobei das natürlich nur ein Beispiel ist und sehr stark von der Gestaltung der Seite abhängt. Nur weil Overhead entsteht, müssen da nicht gleich ‚eine Menge User auf der Strecke bleiben‘. Das passiert eher bei schlecht gecodeten Photoshop-Designs, wo auf CSS(3) verzichtet wird und nachher für jede Kleinigkeit eine Grafik erstellt wird, was dazu führt, dass jede Seite aus 999 Grafiken besteht. Hier ist eine Aufteilung natürlich sehr sinnvoll. Besteht die gesamte Seite aber aus einer Hand voll Grafiken, ist es sinnvoller daraus ein Sprite zu erstellen und den geringen Overhead in Kauf zu nehmen. Die Übertragung von 99 Einzelgrafiken ist nämlich definitiv nicht performanter, im Gegenteil: Jedes mal ein Request-Header, paar Daten kommen an, ein Response-Header und so weiter. Das ist alles Overhead und kostet Zeit. Wenn man aus den 99 Grafiken eine Macht und dadurch ein paar KB Overhead entstehen, wird die Seite bei den meisten Usern dennoch schneller laden, da eine einzelne Datei am Stück immer deutlich schneller geladen werden kann.

    Übrigens verursacht Base64 technisch bedingt Overhead. Pauschal alle verwendeten Bilder Base64 kodiert in CSS-Dateien zu speichern ist also auch nicht sinnvoll, weil so deutlich mehr Traffic entsteht. Base64 ist eine wartungsärmere Alternative für Kleinigkeiten wie Icons. Bei größeren Bildern sind Sprites wieder sinnvoller und der höhere Wartungsaufwand macht sich bezahlt. Generell halte ich aber mehr davon Designs gleich vernünftig zu Coden. Dann hat man nämlich maximal ein paar kleine Icons oder Einzelgrafiken, die kann man dann problemlos Base64 kodiert in die CSS-Datei legen. Ist natürlich aufwändiger bzw. teuerer, aber das ist die Wartung von Sprites auch, und zwar dauerhaft.

    Frameworks selbst zu schreiben halte ich für wenig sinnvoll und verursacht meist mehr Aufwand als Nutzen. Gerade jQuery ist von Haus aus bereits sehr schlank, und man kann sich via custom build bereits selbst eine jQuery-Version erstellen lassen, die nur benötigte Features enthält. Minified + compressed ist jQuery dann im Extremfall gerade mal 10KB groß.

    Einzeldateien zu kombinieren ist natürlich sinnvoll, sofern sich an einzelnen Files nicht öfter was ändert, und dadurch das gesamte Caching im Eimer ist. Hier also ggf. sinnvoll zusammenführen, auch wenn alles in eine Datei auf den ersten Blick am besten erscheint. Aus diesem Grund sollte man von js/css Dateien die dynamisch generiert werden absehen oder diese strikt vom statischen trennen und logischerweise nicht mit Librarys oder ähnlichem kombinieren.

    Man sieht schon an der Länge meines Kommentares, dass es sich um ein ziemlich komplexes Thema handelt, dass man nicht mal eben universell in ein paar Sätzen von A-Z erklären kann. Es gibt verschiedene Optimierungsmethoden, deren Sinn und Erfolg stark davon abhängt was optimiert werden soll. Im schlimmsten Fall kann man mit undurchdachter Optimierung auch das Gegenteil erreichen.

    Reply
  3. Vielen Dank für eure beiden Kommentare. Es stimmt schon. Jedes einzelne Feld hier würde eigentlich ein eigenes Blog Posting ausfüllen. Eure Kommentare geben da auch nochmals sehr viel Input. Vielleicht sollte man das auch noch machen.
    Natürlich muss man immer zwischen dem Für und Wider je nach Anwendungsfall abwägen. Caching z.B. wird natürlich umso irrelevanter, umso seltener die Seite besucht wird. Dann aber sind die Ladezeiten noch wichtiger.
    Die Grundaussage sollte aber sein, dass ein CDN kein Allheilmittel ist sowie etwas Input geben, was stattdessen noch alles vorher gemacht werden kann – Vorausgesetzt, dass es Sinn ergibt.

    Reply
  4. Es kling hier zum Teil so, als sei ein Content Delivery Network dazu da, die Auslieferung von statischen Inhalten zu beschleunigen. Das ist richtig und falsch zugleich. Relevant wird das erst, wenn die Anbindung ans Rechenzentrum zu große Latenzen erzeugt, also für internationale Websites.

    Wer ohne diese Anforderung schnell statische Inhalte ausliefern will, setzt sich einen oder zwei Webserver auf, die besonders schnell ausliefern, schiebt die Daten dahin und passt die URLs in der Website an. Das ist IMHO kein CDN.

    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