Optimierung externer Client-Ressourcen durch Ant-Deploy-Prozess

Auf diesem Blog gibt es viele interessante Beiträge, wie man die Performance serverseitig verbessert.
Eine mindestens genauso gute Möglichkeit für eine Verbesserung der Performance ist, es dem Client-Rechner etwas leichter zu machen. Dieser Beitrag soll einen Überblick über die Möglichkeiten dazu geben.

Engpässe finden
Eine sehr hilfreiche Erweiterung ist die Firefox-Extension YSlow. Diese identifiziert Engpässe und gibt im Yahoo!-Developer-Network direkte Anleitungen und Hilfsmittel. Einige sollen hier näher erklärt werden

Der deploy-Prozess
Viele Punkte in YSlow, wie z.B: „Make fewer HTTP requests“, „Gzip components“ oder „MinifyJS“ können mit dem sogenannten deploy-Prozess erreicht werden. Ein deploy ist eine Methode, die aus den Entwicklungsdateien optimierte Versionen für den online-Einsatz erstellt, z.B. indem Dateien zusammengefasst oder komprimiert werden.

ANT
Ein wunderbares Tool, um den deploy-Prozess umzusetzen, ist ANT. ANT ist ein Java-Tool von Apache Foundation, das entweder als Konsolen-Tool oder aber – was ich wesentlich interessanter finde – als Eclipse-Plugin verwendet werden kann. Verwendet man PHPEclipse, ist ANT direkt vorinstalliert und kann über Window – Show View – ANT eingeblendet werden.

build.xml – Allgemein
ANT wird über eine xml-Datei gesteuert, die build.xml. Diese folgt bestimmten Formalien, damit ANT die Datei versteht. Um die Datei zu verwenden, klickt man in der ANT-View auf die Ameise mit dem grünen Plus daneben und wählt die build.xml-Datei aus. Danach ist der play-Button in der ANT-View aktiv und der deploy-Prozess kann theoretisch starten ????

build.xml – Aufbau
Die build.xml ist in sogenannte tasks untergliedert. Damit kann man seinen deploy-Prozess sauber strukturieren.
Hier mal eine beispielhafte build.xml-Datei:

<?xml version="1.0" encoding="UTF-8"?>
<project name="dein_projektname" default="deploy" basedir="."> 
<property name="tmp" location="Pfad/Zum/Temporaeren/DeployVerzeichnis" /> 
<target name="deploy">
<echo message="Dein deploy-Task"></echo> 
</target>
</project>

Mit einer property kann man eine Variable setzen, auf die dann später mit ${propertyName} zugegriffen werden kann.
In einem target kann man jetzt alle beliebigen ANT-Tasks ausführen.

Konkrete Umsetzung
Nun geht es an die konkrete Umsetzung der Aufgaben „Dateien zusammenfassen“, „Minifyen“ und „Gzip“.

Dateien zusammenfassen
Dieser Teil hat folgenden Vorteil: während der Entwicklungsphase können z.B. CSS-Dateien auseinander gehalten werden (layout.css, colors.css, forms.css), in der Online-Version muss aber nur eine Datei (general.css) vom Server geladen werden. Das bedeutet weniger HTTP Requests und weniger HTML-Code, um die einzelnen CSS-Dateien einzubinden. Um eine zusammengefasste Datei zu erstellen, wird der concat-Befehl verwendet:

<concat destfile="${tmp}/general.css" force="no" fixlastline="true">
    <filelist dir="pfad/zu/deinen/cssdateien">
        <file name="layout.css" />
        <file name="colors.css" />
        <file name="forms.css" /> </filelist>
</concat>

Darin gebt ihr die Zieldatei an und welche Dateien zusammengefasst werden sollen. Damit es kein Durcheinander in den Dateien gibt, die Datei am Besten in ein temporäres Verzeichnis (${tmp}) legen.

Minify
Minify entfernt Leerzeichen und Zeilenumbrüche und ersetzt
function meinLangerFunktionsname()
durch
function A()
Das bringt eine Ersparnis von bis zu 70% in der Dateigröße! Und keine Sorge, dass hier was durcheinander kommt ???? In aktuellen Projekten von mir werden über 100 JavaScript-Dateien damit gehandelt und es funktioniert 1a.
Um ein Minify durchzuführen gibt es verschiedene Tools, die man mit ANT ausführen kann. Ich verwende das von Yahoo. Dafür müsst ihr yuicompressor und YUIAnt runterladen. Anschließend folgenden Code außerhalb eines tasks in eure build.xml einfügen:

<taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">
    <classpath>
        <pathelement path="pfad/zu/den/tools/yuicompressor-2.3.5.jar" />
        <pathelement path="pfad/zu/den/tools/YUIAnt.jar" /> </classpath>
</taskdef>

So, jetzt haben wir die technischen Voraussetzungen, um den minify-Prozess durchzuführen. Das geht so:

<yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true" outputfolder="${tmp}">
    <fileset dir="${tmp}/">
        <include name="**/*.js" />
        <include name="**/*.css" /> </fileset>
</yuicompress>

Zwischenstand
Im temporären Verzeichnis liegen jetzt die zusammengefassen und minifyten JavaScript- und CSS-Dateien. Sind schon schön klein geworden, oder :-)? Um hier noch mehr an der Größe zu tun, können diese Dateien noch gzip-komprimiert werden.

Gzip-Komprimierung
Hierfür sind keine besonderen Tools notwendig, es reicht eine Zeile:

   <gzip src="${tmp}/general.css" destfile="pfad/zu/deinem/htdocs/verzeichnis/general.css"/>
 

Der Gzip-Vorgang kann leider nicht über ein fileset gemacht werden, sondern jede Datei braucht eine eigene Zeile…

Ergebnis
Die Dateien sind jetzt perfekt für den Online-Einsatz vorbereitet und ihr müsst trotzdem kein bisschen auf Übersichtlichkeit oder andere Strukturierung während der Entwicklung verzichten.
Die fertige build.xml sieht so aus:

<?xml version="1.0" encoding="UTF-8"?>
<,project name="dein_projektname" default="deploy" basedir=".">
    
    <property name="tmp" location="Pfad/Zum/Temporaeren/DeployVerzeichnis" />
    
    <taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">
        <classpath>
            <pathelement path="pfad/zu/den/tools/yuicompressor-2.3.5.jar" />
            <pathelement path="pfad/zu/den/tools/YUIAnt.jar" /> </classpath>
    </taskdef>
    
    <target name="deploy">
        <echo message="Dein deploy-Task"></echo>
        
        <concat destfile="${tmp}/general.css" force="no" fixlastline="true">
            <filelist dir="pfad/zu/deinen/cssdateien">
                <file name="layout.css" />
                <file name="colors.css" />
                <file name="forms.css" /> </filelist>
        </concat>
        
        <yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true" outputfolder="${tmp}">
            <fileset dir="${tmp}/">
                <include name="**/*.js" />
                <include name="**/*.css" /> </fileset>
        </yuicompress>
        
        <gzip src="${tmp}/general.css" destfile="pfad/zu/deinem/htdocs/verzeichnis/general.css" /> </target>
</project>

Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0