CSS und Javascript richtig ausliefern

Neben der reinen Suchmaschinenoptimierung gibt es jetzt auch die Abkürzung SPO, oder auch Shop Performance Optimization genannt. Was aber versteckt sich dahinter und wie kann man das grundlegend angehen?

Was versteckt sich hinter SPO?

Wie man bereits weiß wird nach und nach auch die Site-Performance eine Rolle in den SERPS (Search Engine Result Pages) spielen. Dazu zählt beispielsweise der Faktor Zeit eine große Rolle bis die Seite fertig geladen bzw. gerendert ist. Jetzt muss man vorher natürlich etwas die theoretische Seite betrachten um die genauen Sachverhalte für das Wieso nachvollziehen zu können.

Jeder Aufruf einer Datei - sei es ein Bild, ein Filmchen, eine CSS-Datei (Cascading Style Seet) oder eine JavaScript-Datei (wie beispielsweise jquery) wird der Server angewiesen alle Dateien zur Verfügung zu stellen. Der Browser dagegen nimmt diese Dateien an. Soweit so gut, das Problem ist nur dass Browser an kleinere Restriktionen gebunden sind.

  • Viele Browser können lediglich zwei Dateien einer gleichen Quelle parallel downloaden.
  • Werden mehr als zwei Dateien von einer Quelle angefordert werden diese in eine Warteschleife gestellt
  • Jeder Aufruf bedeutet einen HTML-Request. Je mehr es sind, desto länger wird es dauern alle Verbindungen geöffnet und verarbeitet wurden

Hier stellt man unweigerlich fest, dass man selbst bei aktuellen Browsern schnell ein Flaschenhals da sein kann.

Wie sieht der Plan aus? Wie gehen wir vor?

Unser heutiges Ziel soll es sein die Anfragen zu minimieren. Im speziellen geht es mir um die Reduzierung der JavaScript und CSS-Dateien. Dabei möchte ich heute hier auf eine etwas händischere Methode eingehen. Sicherlicht gibt es auch On-The-Fly Methoden in den gängigsten CMS, aber ich möchte ja auch die Grundlagen vermitteln. Denn wer sich selber eine Seite in HTML aufbaut, kann dann immer noch auf diese Resourcen zurückgreifen. Wir realisieren das ganze in der Skriptsprache ruby. Ruby wird uns hier ganz einfach helfen ans Ziel zu kommen. Mit Ruby werden wir die Dateien kombinieren (hier sparen wir wichtige Aufrufe) und komprimieren (spart uns wichtige Bandbreite). Wer Interesse hat, den Originalbeitrag "How to automate optimization and deployment of static content" findet man bei smashingmagazin.com.

Vorbereitungen

Wer mit einem Apple arbeitet kann sich jetzt ganz entspannt zurücklehnen, denn auf Mac-Rechnern ist Ruby bereits vorinstalliert. Anders bei Windows. Hier muss man das ganze erst einmal nachinstallieren. Hierzu lädt man sich schlicht von der Herstellerseite das passende Paket für Windows herunter und installiert dies. Ist die Installation von Ruby fertig kann man die Konsole ganz einfach mit Ruby-Unterstützung starten.

Damit haben wir aber ersteinmal nur die halbe Miete. Wir brauchen natürlich auch die nötigen Addons für Ruby.
Eines davon ist Juicer, welches von Christian Johansen entwickelt wurde. Mit diesem Tool werden unsere Javasckripte und CSS kombiniert und komprimiert.
Um Juicer zu installieren benötigen wir folgende Zeile in unserer Kommandozeile


    	Windows: gem install juicer
    	Mac OS X: sudo gem install juicer

Nicht wirklich viel Unterschied, nur lediglich 4 Buchstaben. Damit Juicer auch richtig arbeitet benötigen wir hier noch zwei Komponenten. YUI-Kompressor und JSlint. Wesentlich schwieriger gestaltet sich das auch nicht. Hier brauchen wir zwei Zeilen:


    	juicer install yui_compressor
    	juicer install jslint

Hat man beide Zeilen eingegeben steht einem das Optimieren seiner Dateien nichts mehr im Wege

Fangen wir an

Nehmen wir der Einfachkeit halber an, wir bauen uns ein kleines HTML-Template auf das später einmal eine kleine statische HTML-Seite werden soll. Grundlegend ändert sich nichts an der Art wie wir Dateien optimieren und komprimieren. Es unterscheidet sich dann lediglich nur wo die Dateien liegen und wie diese eingebunden werden.
Unsere Seite soll folgende Elemente beinhalten:

  • 960er Grid-System von 960.gs
  • Eine eigene Stylesheet Datei
  • Diverse Javascript - Dateien (Framework, seperate Dateien - egal was)

Damit Ihr Euch vorstellen könnt wie die HEAD-Anweisung aussieht hier einen Auszug aus genanntem Bereich:


		<head>
		<title>Juicer-Demo ohne Optimierung</title>
		<link rel="stylesheet" href="css/reset.css">
		<link rel="stylesheet" href="css/960.css">
		<link rel="stylesheet" href="css/text.css">
		<link rel="stylesheet" href="css/style.css">

		<script type="text/javascript" src="js/jquery-1.2.6.js"></script>
		<script type="text/javascript" src="js/jquery.pagination.js"></script>
		<script type="text/javascript" src="js/jquery.pageigen.js"></script>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	</head>

Allein mit diesen Zeilen haben wir bereits 7 (!!) HTTP-Requests. Was haben wir oben gelernt? Ein Browser kann immer zwei Dateien parallel downloaden, der Rest ist in der Warteschlange. Das bedeutet dass wir mind. 3x2 und 1x1 Datei laden. Das sich das ganze auch auf die Ladezeit ausübt sieht man an folgendem Screenshot.

Dieser wurde mit Safari aufgenommen und zeigt deutlich das Ladeverhalten. Je nachdem ob die Dateien gecached sind ändern sich natürlich die Zeiten. Aber wie man hier sieht hat man mit den vorangehenden HTML-Block 706 ms benötigt (ok, der vServer ist nicht der schnellste, aber es zählt ja das Prinzip ;) ). Jetzt stellt man sich das ganze mal bei vielen Skripts, vielen CSS und noch mehr Bildern vor. Da ist man sehr schnell am Flaschenhals.

Steuerungsdateien vorbereiten

Da wir nun dem Ruby-Plugin Juicer mitteilen müssen welche Dateien kombiniert werden sollen, müssen wir vorher Steuerungsdateien anlegen. In diesen Dateien teilen wir juicer mit welche Dateien optimiert und kombiniert werden sollen.
Fangen wir zunächst mit den CSS-Dateien an. Wichtig ist hier, dass man sich an die Reihenfolge hält da sonst die Ausgabe anders wird wie gewohnt bzw. wie erwartet.
Legen wir uns im css-Ordner eine Datei namens combined.css an und füllen diese mit folgendem Inhalt:


	@import url("reset.css");
	@import url("960.css");
	@import url("text.css");
	@import url("style.css");

Nicht allzu schwierig oder? Wir importieren lediglich alle anfallenden css-Dateien. Dasselbe Prinzip greift auch bei den js-Dateien, jedoch mit etwas anderem Inhalt:


	/**
	* @depends jquery-1.2.6.js
	* @depends jquery.pagination.js
	* @depends jquery.pageigen.js
	*/

Auch hier gilt, first things first. Was zu erst geladen werden muss, muss auch zu erst als depend markiert sein.

Jetzt kommt der Moment auf den wir alle gewartet haben. Lassen wir den Zauber beginnen. Betrachten wir uns vorher noch einmal die Dateigrößen:

  • Stylesheets - 4 Dateien - 24 kb
  • Javascripts - 3 Dateien - 108 kb

Beim jquery habe ich bewusst eine unkomprimierte Datei gewählt um den Effekt zu demonstrieren.

Wechseln wir zunächst in den css-Ordner. Dazu bemühen wir unsere Konsole bzw. unsere Kommandozeile. Hier geben wir folgenden Code an:


	juicer merge --force combined.css

Das Ergebnis hier ist eine combined.min.css. Die Größen verrate ich gleich. Wiederholen wir den Vorgang für die javascripts.


	juicer merge -i --force combined.js

Fällt das -i auf? Das bedeutet lediglich das jslint (Modul von juicer) auch bei Fehlern im Skript die Arbeit trotzdem fortführt.
Jetzt wären wir soweit fertig, sehen wir uns die neuen Dateien an:

  • Stylesheets - 1 Datei - 12 kb
  • Javascripts - 1 Datei - 61 kb

Das macht in der Summe 59 kb weniger, eine Einsparung von knapp 44,7%. Wenn man nun ca. 50 Besucher am Tag hat kommt das bereits auf eine Traffic-Reduzierung von 2,88 MB.
Toll oder? Jetzt ändern wir unseren Code folgendermaßen ab:


	<head>
		<title>Juicer-Demo mit Optimierung</title>
		<link rel="stylesheet" href="css/combined.min.css">
		<script type="text/javascript" src="js/combined.min.js"></script>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	</head>

Sieht man sich jetzt die Grafik von Safari an, merkt man ganz schnell das unsere Aktion Früchte getragen hat. Wir bewegen uns jetzt bei 512 ms, also fast 200 ms schneller als ohne die Optimierung - und das bei kleinen Dateien. Man stelle sich das jetzt bei einer kompletten Stylesheet - Sammlung vor.

Demo der beiden Varianten

Wer sich das gerne live anschaut, kann beide Links einmal klicken um das Ergebnis selber zu betrachten:

Abschließendes und künftiges

Sicherlich gibt es auch viele Tools wie ScriptCompressor (WordPress) oder Fooman Speedster (Magento) die das alles bereits on-the-fly und automatisch machen. Wenn diese gecached werden natürlich umso besser. Aber Fakt ist hier, dass der Serverprozessor beansprucht wird. Man sollte aber auch die theoretischen Grundlagen wissen, wie solche Tools arbeiten. Im nächsten Post zu diesem Thema werden wir das ganze etwas automatisieren, auch mit Hilfe von ruby. Wir gehen dazu über das wir das für ein einzelnes Projekt nur noch eine Zeile ausführen müssen, die uns die Dateien optimiert, komprimiert und anschließend in gzip umwandelt.

Ich hoffe der Post war einigermaßen verständlich. Wie optimiert Ihr Eure Dateien? Ihr seid gerne eingeladen Euch in den Kommentaren auszulassen.


Alle Posts der Woche 35 / 2010 anschauen

Fandest Du den Beitrag interessant?

Der Beitrag ist mir etwas wert:
Fatal error: Call to undefined function the_flattr_permalink() in /var/www/html/web1028/html/seo-geek-de/wp-content/themes/seogeek/single.php on line 48