Wenn man mehrere CSS- oder Javascriptdateien auf einer Webseite benutzt, kann die Performanz der Seite erhöht werden, indem diese Dateien typweise in eine große Datei kombiniert werden. Diese Technik ist auch unter dem englischen Namen "suturing" bekannt, was aus dem englischen Medizinwortschatz entlehnt ist und in etwa "(zusammen)nähen" bedeutet.
Als Beispiel wird im nachfolgenden Artikel die Einbindung der Stylesheets auf dieser Webseite beschrieben.
Auf der www.standardized.de werden aktuell drei Stylesheets verwendet:
Um diese getrennt zu laden, müsste der Browser drei Anfragen an den Webserver schicken. Da die Dateien sehr klein sind, dauert das Stellen der Anfragen länger als die eigentliche Auslieferung. Außerdem kann der Benutzer das Verbindungslimit für Anfragen an die gleiche Domain erreichen, wenn es noch viele andere Objekte zu laden gibt (z.B. Javascripte und Bilder). Durch das Zusammenfassen der Dateien zu einer werden diese Probleme umgangen.
Im folgenden betrachten wir, wie diese Technik mit Silverstripe angewendet werden kann, welche Hindernisse dabei auftreten und wie sie überwunden werden können.
Externe Dateien werden in Silverstripe mit Hilfe der Requirementsklasse eingebunden; sie kann sowohl im Template als auch im Controller genutzt werden. Die Dokumentation zur Klasse ist unter "http://api.silverstripe.org/default/Requirements.html" zu finden.
<html>
<head>
<% require themedCSS(reset) %>
<% require themedCSS(base) %>
<% require themedCSS(tipTip) %>
</head>
</html>
class Home_Controller extends ContentController
{
public function init()
{
parent::init();
Requirements::themedCSS(reset);
Requirements::themedCSS(base);
Requirements::themedCSS(tipTip);
}
}
Um mehrere Dateien zusammenzufassen, müssen wir mit dem Controller in der Methode "init()" beginnen.
Als erstes definieren wir ein numerisches Array, in dem die einzelnen Dateien inklusive Pfad (ausgehend vom Rootverzeichnis) gespeichert werden:
$currentTheme = SSViewer::current_theme();
$cssArray = array(
'themes/'.$currentTheme.'/css/reset.css',
'themes/'.$currentTheme.'/css/base.css',
'themes/'.$currentTheme.'/css/tipTip.css'
);
Im nächsten Schritt geben wir der Klasse Requirements alle Dateien bekannt, die wir einbinden wollen:
foreach($cssArray as $css)
{
Requirements::css($css);
}
Abschließend sagen wir der Klasse, dass diese Dateien kombiniert werden sollen und übergeben ihr den Ablageort und -namen der kombinierten Datei, sowie die zu kombinierenden Einzeldateien und führen den Kombinationsprozess aus:
Requirements::combine_files(
'assets/suture.css',
$cssArray
);
Requirements::process_combined_files();
Die kombinierte Datei heißt also "suture.css" und liegt im Verzeichnis "assets". Warum sie dort abgelegt wird, wird im Abschnitt "Der richtige Ablageort für die zusammengefasste Datei" erklärt.
Auf den ersten Blick mag es umständlich erscheinen, der Methode "combine_files" die zu kombinierenden Dateien in einem Array (hier "$cssArray") übergeben zu müssen, sie kennt zu diesem Zeitpunkt ja schon die Dateien, die eingebunden werden sollen.
Der Vorteil dieser Maßgabe ist, dass man viele Dateien als Requirement heranziehen kann, aber nur eine Auswahl davon zusammenfassen lässt. Wenn man Dateien zusammenfasst, sollte man die nehmen, die auf allen (oder den meisten) Seiten verwendet werden, um den Browsercache effektiv zu nutzen. Wir können uns also ein Szenario vorstellen, bei dem auf der Seite "Home" neben der kombinierten Datei "suture.css" - deren Angaben auch auf allen anderen Seiten benötigt werden - noch ein weiteres Stylesheet herangezogen wird, das Inhalte exklusiv für diese Seite formatiert.
Hier ist der komplette Quelltext für den Controller:
class Home_Controller extends ContentController
{
public function init()
{
parent::init();
$currentTheme = SSViewer::current_theme();
$cssArray = array(
'themes/'.$currentTheme.'/css/reset.css',
'themes/'.$currentTheme.'/css/base.css',
'themes/'.$currentTheme.'/css/tipTip.css'
);
foreach($cssArray as $css)
{
Requirements::css($css);
}
Requirements::combine_files(
'assets/suture.css',
$cssArray
);
Requirements:process_combined_files();
}
}
Beim Aufruf der Seite wird die Datei "suture.css" im Verzeichnis "assets" erzeugt. Diese wird durch die Requirementsangaben im Controller (siehe vorheriger Abschnitt) automatisch im Template eingebunden.
Im Abschnitt "Definieren der Requirements und Zusammenfassung im Controller" haben wir festgelegt, dass die kombinierte Datei im Verzeichnis "assets" abgelegt werden soll statt im CSS-Verzeichnis des Themes.
Der Grund dafür ist, dass das Verzeichnis vom Webserver beschreibbar sein muss. Das Themes-Verzeichnis sollte bei einer sauberen Installation keine Schreibmöglichkeit für den Webserver bieten; Silverstripe sieht für solche Dateien das Verzeichnis "assets" vor, für das es schon bei der Installation Schreibzugriff fordert.
Wenn man im Stylesheet Hintergrundbilder mit einem Pfad definiert und die zusammengesetzte Datei im Verzeichnis "assets" ablegen lässt, werden diese entweder im Entwicklungsmodus oder im Livemodus nicht gefunden, da der Pfad in der Regel aus dem Verzeichnis "templates" heraus gesetzt wird. Um das zu verhindern, kann die Klasse "Requirements" angepasst werden, so dass das Suturing auch im Entwicklungsmodus stattfindet.
Dazu wird in der Klasse Requirements aus "sapphire/core/" die Zeile 819
if((Director::isDev() && !SapphireTest::is_running_test()) || !Requirements::get_combined_files_enabled()) {
ersetzt durch
if((!Requirements::get_combined_files_enabled())) {
Die Klasse Requirements ist so geschickt angelegt, dass die kombinierte Datei nicht bei jedem Seitenaufruf neu erzeugt wird; damit ist der Overhead für das Kombinieren von Dateien sehr gering.
Die Datei wird nur dann neu erzeugt, wenn:
Folgendes sollte beachtet werden, wenn man Dateien kombiniert:
Dokumentation der Klasse "Requirements" auf api.silverstripe.org:
http://api.silverstripe.org/default/Requirements.html
Allgemeines zur Verwendung von Requirements in der Silverstripe Dokumentation:
http://doc.silverstripe.org/doku.php?id=requirements
Das "Rezept" zum Zusammenfassen von Requirements in der Silverstripe Dokumentation:
http://doc.silverstripe.org/doku.php?id=recipes:combining_files
Artikel zur Suture-Technik auf Websiteoptimiziation.com (englisch):
http://www.websiteoptimization.com/speed/tweak/suture/
Bisher hat niemand diese Seite kommentiert.
RSS Feed für die Kommentare auf dieser Seite | RSS feed für alle Kommentare