Einleitung
Mehrere Dateien im Header (oder allgemein in der Seite) einzubinden bedeutet: der Webbrowser des Besuchers meiner Webseite muss mehr Requests absetzen, bevor er die Seite anzeigen kann.
Ja das kann doch aber minimieren! Die Suchmaschine deiner Wahl liefert mit den Begriffen compress oder minify und css oder js so einige weiterhelfende Treffer.
Und die nachfolgende Klasse ist meine Lösung...
Meine Klasse staticfilesmacht im ersten Schritt Folgendes:
- sie nimmt alle js und css Dateien entgegen
- Die Javascripts und CSS Dateien werden zu je einer Datei zusammengefasst. Bei CSS-Dateien werden die ggf. enthaltenen relativen Verweise zu Referenzen mit absolutem Pfad umgeschrieben.
- unnötige Leerzeichen, Tabs etc. werden entfernt
- Die zusammengefassten (germergten) Dateien werden als Cachedatei abgelegt. Eine Caching Logik aktualisiert den Cache, sobald die Caching-Zeit abgelaufen ist oder aber sich eine der in derselben Gruppe eingebundenen Dateien geändert hat.
- Ausgegeben wird im Html-Dokument die Verlinkung zum Cachefile
Updates:
- 2018-07-23:
- Fix bei Kompression für JS als auch CSS - 2012-10-09:
- writeMedia Methode erhielt einen 2. Parameter zum Filtern - 2012-07-05:
- fixed: CSS-Default Media Attribut wurde von "screen" auf "all" geändert.
- added: beim Komprimieren von CSS werden nun auch Kommentare entfernt. - 2012-06-30:
- fixed: im Debugmodus wurde der einleitende Kommentar nicht korrekt geschlossen
- fixed: Methode addCss nimmt als 2. Parameter nun auch Media-Attribute mit Selektoren auf
Voraussetzung
- PHP 5
- Javascript- und Stylesheet-Dateien sind am eigenen Webserver
- Pfade zu Javascript- und Stylesheet-Dateien erfolgt mit absolutem Pfad
- Zugriff auf Webserver-Konfiguration zum Aktivieren der gzip Kompression (beim Apache reicht es auch, wenn .htaccess erlaubt ist)
Installation
Download
staticfiles_class_php.zip (19 kB)
Auspacken
Kopieren Sie die Datei staticfiles.class.php in ihr PHP-Verzeichnis. Sie kann auch in einem beliebigen Unterordner abgelegt werden.
Einbindung in deine Webseite
(1)
In deiner PHP-Datei, die den HTML-Header ausgibt, ist die Klasse einmalig einzubinden:
require_once("/php/staticfiles.class.php"); $o=new Staticfiles();
(2)
Es gibt 2 Funktionen, mit denen Javascript- und CSS-Dateien hinzugefügt werden.
Javascript:
$o->addJs([JS-Dateiname]); oder $o->addJs([JS-Dateiname], "defer");
... und die CSS-Dateien:
$o->addCss([CSS-Dateiname]); oder aber $o->addCss([JS-Dateiname], [Media-Attribut]);
(3)
Die Cachefiles, die alle Dateien zusammenfassen zu erzeugen und die Ausgabe der Links für den HTML-Header erfolgt mit
$o->writeMedia("js", "execution"); $o->writeMedia("css");
und am Ende des Html-Body:
$o->writeMedia("js", "defer");
Gzip-Kompression und Caching am Client
Es gibt in der Klasse zwar eine Funktion zur Komprimierung des Codes. Diese entfernt überflüssige Tabs und Leerzeichen. Dies spart ca. (lächerliche) 2% des Codes ein. Dies lässt sich um ca. 70..80% drücken, wenn man die gzip-Kompression auf dem Webserver für .css und .js Dateien aktiviert.Eine zweite am Webserver notwendige Einstellung ist das Caching am Client. Dies legt fest, wie lange ein Webrowser eine einmal abgerufene Datei im Browsercache festhalten soll.
Apache
Nachfolgender Code gilt für den Apache Webserver.# gzip Kompression einschalten: mod_gzip_on Yes # Client-Cache aktivieren ExpiresActive On ### 2 days im Browsercache belassen ExpiresByType application/x-javascript "access plus 2 days" ExpiresByType application/javascript "access plus 2 days" ExpiresByType text/css "access plus 2 days"
Nginx
... oder für Nginx:Die Kompression kann man global für alle Webs in der Server-Sektion einschalten.
# gzip Kompression einschalten: gzip on; gzip_types text/css text/javascript;
Das Expire lässt sich im im virtuellen Host setzen.
location ~ \.(css|js)$ { (...) # Client-Cache aktivieren expires 2d; }
Debugging
In der eigenen Entwicklungsumgebung braucht man zumeist die Originaldateien im Zugriff. Bei dieser Klasse kann man sowohl Debugging-Informationen einschalten als auch die Original-Dateien einbinden.
Die Debug Informationen erscheinen im HTML-Code als HTML-Kommentar.
In meiner Entwicklungsumgebung heissen die Hosts local.[domainname] - das fange ich per Matching auf $_SERVER["SERVER_NAME"] ab.
require_once("/php/staticfiles.class.php"); $o=new Staticfiles(); // Test, ob ich in der Entwicklungsumgebung bin if (strpos($_SERVER["SERVER_NAME"], "local.")===0) { $o->setDebugDefaults(); // schaltet Debug Infos ein // Paranaoia-Option: wenn man Fehler der Klasse ausschliessen will: $o->setMerging(false); // schaltet Merge aller Dateien aus und bindet Links zu Originalfiles ein } // hier geht es weiter mit addJS und addCss ...
Komplettes Beispiel
Ausgangslage: CSS-Dateien und Javascripts sind im Header des HTML-Dokuments:
Statt der Link- und Script-Tags werden die Methoden zum Hinzufügen angewendet. Mit writeMedia erfolgt die Ausgabe:
Die Funktionen writeMedia erzeugen/ aktualisieren im Hintergrund die Cachefiles und im Vordergrund wird diese Ausgabe erzeugt:
Dokumentation
__construct | public | __construct() init function; it sets defaults. @return bool (dummy) | |
_genHtml | private | _genHtml( generate html code to link the cachefile (or original files if cache is disabled) @param string $sType type; one of css|js @param array $aFile array with filedata (keys are attributes) @return string html code | |
_getStats | private | _getStats( show some statistics info about code compression an gzip @param type $sOrig @param type $sCrunched @param type $sCommment @return type | |
_log | private | _log( write logging information (only if debug is enabled) @param type $s @return type | |
addCss | public | addCss( add a css file to this object @param string $sFile path and filename of css file like in href attribute @param string $sMedia media type @param title $sTitle title (will be ignored so far) @return bool (dummy) | |
addJs | public | addJs( add a js file to the js array @param string $sFile file to load @param string $sDefer @return type | |
addMedia | public | addMedia( add media file to array; it is called by addJs() and addCss() @param string $sType one of css|js @param array $aFiledata; Keys: file: filename; other: attributes @return type | |
compressCss | public | compressCss( compress css code: remove spaces, tabs, line breaks @param string $s css data @return string rewritten css data | |
compressJs | public | compressJs( compress js code @param string $s js code @return string with new js code | |
getCacheBase | public | getCacheBase() get current basepath of cache @return boolean | |
getCacheDir | public | getCacheDir() get full path of current cache directory @return boolean | |
getDebug | public | getDebug() get current debug flag @return boolean | |
getMerging | public | getMerging() get current merge flag @return boolean | |
getMinCacheTime | public | getMinCacheTime() get current caching time on server @return integer | |
getRewriteCache | public | getRewriteCache() get current flag to rewrite the cache @return boolean | |
rewriteCss | public | rewriteCss( rewrite urls in css data; this function finds relative pathes and rewrites them to absolute pathes @param string $s css content @param string $sFile filename of included css (to detect the "current" path) @return string the reswritten css code | |
setCacheBase | public | setCacheBase( set another basepath (behind webroot) @param string new basepath @return boolean | |
setCacheDir | public | setCacheDir( set another cache directory. @param string new basepath (below webroot) @return boolean | |
setDebug | public | setDebug( set debug flag (for development environment) @param boolean set true to enable debug output @return boolean | |
setDebugDefaults | public | setDebugDefaults() set debug default settings @return bool (always true) | |
setDefaults | public | setDefaults() set all vars to initial values @return bool (always true) | |
setMerging | public | setMerging( set merge flag (for development environment) @param boolean set false to disable the generation of merged cachefiles @return boolean | |
setMinCacheTime | public | setMinCacheTime( set minimum cachetime on server for merged js and css files @param integer value in seconds @return boolean | |
setRewriteCache | public | setRewriteCache( set flag bRewriteOnEachRequest (for development environment) @param boolean set true to ignore caching time @return type | |
writeMedia | public | writeMedia( Merge original files of a group to a single cachefile. It updates or just touches the cachefile. Output is the html code to include the cached css/ js in the html header. @param string $sType one of css|js @param string $sMyGroup filter group (given 2nd parameter in addCss or addJs); i.e. "defer" and "execution" for javascripts or a media attribute for css @return bool (dummy) |
$_aStatic | private | $_aStatic = Array ( [js] => Array ( [files] => Array ( ) [tplHtml] => [fRewrite] => [fCompress] => compressJs ) [css] => Array ( [files] => Array ( ) [tplHtml] => [fRewrite] => rewriteCss [fCompress] => compressCss ) ) configuration array @var array |
$bDebug | public | $bDebug = false flag: show debug output? If it is true then you see the merged files, replacements and statistic data in the html header section (as comment) @var boolean |
$bMerging | public | $bMerging = false flag: merge files into a cachefile? If it is false then the source files will be used. This is helpful in the development environment to debug code with original files. @var boolean |
$bRewriteOnEachRequest | public | $bRewriteOnEachRequest = false flag: overwrite cachefile on each request? You can use it in your development environment. It overrides the setting of $this->iMinCacheTime and regenerates merged cachefiles on each request. debug code with original files. @var boolean |
$iMinCacheTime | public | $iMinCacheTime = 3600 minimum time to cache js and css cachefile on server - even if one of the source files have been changed. @var integer |
$sCacheBase | public | $sCacheBase = /~cache/staticfiles/ name for basepath behind webroot @var string |
$sCacheDir | public | $sCacheDir = false absolute path of cache directory; it will be set in the method setDefaults to [document root]/$this->sCacheBase/ @var string |