Programmierung

Javascript- und CSS-Dateien komprimiert ausliefern

  • 28/08/2012

Von modernen Webseiten sind Javascript-Frameworks nicht mehr wegzudenken. Mit den wachsenden Anforderungen erhöhten sich im laufe der Zeit auch die Dateigrößen. Unkomprimiert erreichen die Frameworks mittlerweile 100 kb und mehr. Die Nutzung unterschiedlicher Javascript-Technologien (z.B. Slideshow, Ajax, Lightbox, …) werden zudem modular auf mehrere Dateien verteilt.

Viele und dazu große Dateien können zu Performanceeinbußen bei der Auslieferung der Webseite führen. Webentwickler haben stets die Aufgabe die Dateigrößen und die Anzahl der Requests (Anfragen an den Server) möglichst gering zu halten, um den Server nicht mit unnötigen Anfragen zu belasten.

Wir möchten in diesem Artikel eine Hilfestellung bieten Optimierungen durchzuführen.

Dateigrößen gering halten

Im ersten Schritt werden die Dateien selbst komprimiert. Dazu steht uns eine Vielzahl an Tools zur Verfügung. Um nur einige zu nennen:

Die genannten Tools komprimieren die Dateien, indem sie Kommentare, unnötige Leerzeichen und Tabs entfernen und den Code optimieren.

Da wir eine Javascript und CSS Kompression durchführen möchten, haben wir uns im Artikel für YUI Compressor von Yahoo entschieden. YUI Compressor ist eine Java Anwendung, die an einem beliebigen Ort auf dem Rechner entpackt werden kann. Der Aufruf erfolgt über die Kommandozeile:

java -jar yuicompressor-x.y.z.jar

Ein Beispielaufruf zum komprimieren könnte wie folgt aussehen:

java -jar yuicompressor-x.y.z.jar myfile.js -o myfile-min.js

Im nächsten Schritt aktivieren wir zusätzlich eine GZIP-Komprimierung der Dateien durch den Server mittels .htaccess Eintrag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# GZIP aktivieren
AddEncoding gzip .gz
<filesmatch "\.js\.gz$">
AddType "text/javascript" .gz
</filesmatch>
<filesmatch "\.css\.gz$">
AddType "text/css" .gz
</filesmatch>
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME} \.(js|css)$
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]
</ifmodule>

Sollte ein Browser GZIP nicht untersützen, wird die durch YUI komprimierte Datei ausgeliefert. Andernfalls wird die Datei doppelt komprimiert ausgeliefert.

Die genannten Schritte können auch einzeln umgesetzt werden. Es empfiehlt sich jedoch beide zu nutzen, um die auszuliefernden Dateien möglichst klein zu halten.

Anzahl der Requests minimieren

Nun, da wir die Dateigrößen verringert haben, müssen wir uns um die Anzahl der Serveranfragen kümmern. Jede einzelne Datei, die vom Server ausgeliefert wird, kostet den Server Ressourcen. Die Auslieferung vieler Dateien kann zu Performanceeinbußen führen – auch wenn diese nur wenige Bytes groß sind. Aus dem Grunde ist es in den meisten Fällen besser eine etwas größere Datei auszuliefern als viele kleine.

Das o.g. Tool zur Kompression bietet uns allerdings keine Möglichkeit viele Javascript oder CSS Dateien zu einer einzigen zu verbinden. Folgendes Unix-Script schafft Abhilfe und verbindet die Aufgaben „Komprimieren“ und „Dateien zusammenführen“. Abgelegt wird das Script in einem Scriptverzeichnis, das sich außerhalb der Struktur der Webseiten-relevanten Dateien befindet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash

echo "compressor start"

###############
# Konfiguration
###############

#name der Gesamtdatei
nameComplete="ni_complete"
#Pfad zum YUI Kompressor
path2yuicompressor="yuicompressor/build/yuicompressor-2.4.7.jar"

# Javascript Dateien
path2js="../htdocs/de/js/"
jsFiles[0]="licenses"
jsFiles[1]="jquery-1.7.2.min"
jsFiles[2]="jquery-ui-1.8.20.custom.min"
jsFiles[3]="jquery.easing.pack"
jsFiles[4]="jquery.slider"
jsFiles[5]="ni"

# CSS Dateien
path2css="../htdocs/de/css/"
cssFiles[0]="normalize"
cssFiles[1]="slider"
cssFiles[2]="ni"

###############
# Funktion
###############

# $1 = Typ (JS oder CSS)
# $2 = Path2 HTdocs files (path2js="../htdocs/de/js/")
function build_files {

if [ "$1" == "js" ]; then
theFiles=(${jsFiles[*]})
else
theFiles=(${cssFiles[*]})
fi

path2files=$2

#Datei zu beginn leeren
1>$path2files$nameComplete.$1

for theFile in ${theFiles[@]}; do
if [ "$theFile" == "licenses" ]; then
# Lizenz-Kommentare nicht entfernen
cat $path2files$theFile.$1 >> $path2files$nameComplete.$1
else
# Komprimieren und unter *.min.js abspeichern
java -jar $path2yuicompressor $path2files$theFile.$1 -o $path2files$theFile.min.$1
# Alle minified Dateien zu einer zusammenführen
cat $path2files$theFile.min.$1 >> $path2files$nameComplete.$1
# aufräumen
rm $path2files$theFile.min.$1
fi
done
}

###############
# Funktionsaufruf
###############

build_files "js" $path2js
build_files "css" $path2css

echo "compressor ende"

Im Script wird auch ein Sonderfall behandelt, der noch erwähnt werden muss. Wenn wir Javascript Plugins verwenden, ist in den Lizenzvereinbarungen verankert, dass der Autor und dessen Webseite genannt werden muss. Diese Informationen können in die „licenses.js“ eingefügt werden. Das Script wird diese Datei nicht durch den YUICompressor komprimieren.