Jede CSS-Datei automatisch mit php optimieren
31. Mai. 2016
Um diese Website zu verbessern musste ich mich mit der Optimierung von CSS-Dateien auseinandersetzen. Da ich jedoch kein passendes PlugIn für WordPress fand, welches zuverlässig das erledigt was ich wollte, entschied ich mich selber ein Script für diesen Zweck zu schreiben.
Zielsetzung
Ich setzte mir folgende Vorgaben:
- natürlich sollte das Script keinerlei Einfluss auf die Funktionsweise habe oder sonstige Einschränkungen zur Folge haben
- Das Programm soll vollkommen automatisch CSS-Dateien komprimieren
- Die CSS-Dateien sollen weiterhin normal aufgerufen werden können
- Das Zusammenfügen von CSS-Dateien ist KEIN Ziel
Grundkonzept
Anhand dieser Vorgaben entwickelte ich folgendes Konzept:
- Jede Anfrage einer CSS-Datei soll per .htaccess an ein PHP-Script weitergeleitet werden.
- Das PHP-Script soll überprüfen ob an dem aufgerufenen Ort eine .min.css vorhanden ist, wenn ja soll diese direkt ausgegeben werden.
- Sollte keine minimierte Version existieren soll diese erstellt werden und auf dem Server gecached werden.
Script
.htaccess-Weiterleitung
Zunächst einmal müssen wir alle Anfragen nach einer css-Datei auf unsere zukünftige PHP-Datei weiterleiten. Dazu nutzen wir folgenden Code und speichern Ihn in einer „.htaccess“ Datei auf unserem Server.
<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On # min-CSS ----------------------------------------------------------------------------------- # Add any directories you wish to omit from the min-CSS process on a new line, as follows: # RewriteCond %{REQUEST_URI} !ignore-this-directory # RewriteCond %{REQUEST_URI} !and-ignore-this-directory-too # Send any css request that IS NOT stored inside one of the above directories # to mincss.php to minimize it RewriteRule \.(?:css)$ mincss.php # END min-CSS ------------------------------------------------------------------------------- </IfModule>
PHP-Script
Als Vorlage für die Komprimierung per PHP diente das GitHub-Projekt von „manastungare“, welches ich auf meine Bedürfnisse anpasste.
Entstanden ist folgendes Script:
<?php /* CONFIG ----------------------------------------------------------------------------------------------------------- */ // 604800 $browser_cache = 604800; // browser cache time in seconds $cache_folder = "wp-content/cache/mincss/"; // cache-folder on server $cache_ext = '.mincss'; // file extension $dynamic_url = preg_replace("/\?.+/", "", ($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])); // requested dynamic page (full url) $cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file /* END CONFIG ---------------------------------------------------------------------------------------------------------- ------------------------ Don't edit anything after this line unless you know what you're doing ------------------------- --------------------------------------------------------------------------------------------------------------------- */ $org_file = getfileurl($dynamic_url); // server-path to the css file // path to a possible .min.css file -> already optimized by hand if (strpos(org_file, '.min.css') !== false) { $min_file = org_file; } else{ $min_file = str_replace(".css", ".min.css", org_file); } function getfileurl ($org_file_path) { $org_file_path = str_replace("https://", "", $org_file_path); // remove https:// $org_file_path = str_replace("http://" , "", $org_file_path); // remove http:// $dir = $_SERVER[HTTP_HOST].dirname($_SERVER['PHP_SELF']); // path of the php file $file_path = str_replace($dir."/", "", $org_file_path); // path to read the css file return $file_path; } function readf($filepath){ return file_get_contents($filepath); } function writef($filepath, $content){ // create folder where the file should be stored if not exist if(!file_exists(dirname($filepath))){mkdir(dirname($filepath), 0777, true);} $handle = fopen($filepath,"w"); fwrite($handle, $content); fclose($handle); } function cached($filepath){ if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) <= time()) { header('HTTP/1.1 304 Not Modified'); header("Cache-Control: public, max-age=604800"); exit(); }}} function send($filepath){ $createtime = date(filemtime($filepath)); //header("HTTP/1.1 200 OK", true); header("Content-Type: text/css"); header("Cache-Control: private, max-age=".$browser_cache); header('Last-Modified: '.gmdate('D, d M Y H:i:s', $createtime).' GMT'); $cssc = readf($filepath); ob_start("ob_gzhandler"); // Enable GZip encoding. echo $cssc; // Write everything out } function minimize($rawcss){ $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $rawcss); // Remove comments $buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer); // Remove space after colons $buffer = preg_replace('/ {2,}/', ' ', $buffer); // Collapse adjacent spaces into a single space $buffer = str_replace( ' @', '@', $buffer); // Remove spaces that might still be left where we know they aren't needed $buffer = str_replace( ': ', ':', $buffer); $buffer = str_replace( '{ ', '{', $buffer); $buffer = str_replace( ' {', '{', $buffer); $buffer = str_replace( '} ', '}', $buffer); $buffer = str_replace( ' }', '}', $buffer); $buffer = str_replace( '; ', ';', $buffer); $buffer = str_replace( ' ;', ';', $buffer); $buffer = str_replace( ', ', ', ', $buffer); $mincss = str_replace( ' ,', ' ,', $buffer); $mincss = str_replace( ';}', '}', $buffer); return $mincss." "; } if (!(file_exists($org_file))) { header("HTTP/1.0 404 Not Found"); exit(); } else{ if (file_exists($min_file)) { // minimized version exist --> send minimized version cached($filepath); send($min_file); } elseif (file_exists($cache_file) && (filemtime($org_file) < filemtime($cache_file)) ) { // cache ist aktuell cached($filepath); send($cache_file); } else { // cache ist veraltet $rawcss = readf($org_file); // read original file $mincss = minimize($rawcss); // minimize CSS writef($cache_file, $mincss); send($cache_file); } } ?>
Dieses Script liest die aufgerufene URL aus und prüft ob eine minimierte Version existiert, wenn nicht wird diese erstellt, gespeichert und ausgegeben. Genau so, wie ich es wollte.
Wichtig ist, dass die .htaccess-Datei und das PHP-Script im selben Ordner liegen und, dass das Script nur für Dateien funktioniert die im selben Ordner wie das Script, bzw. in allen Unterordnern liegen funktioniert! Somit sollte möglichst das ROOT-Verzeichnis gewählt werden.
Das ist auch schon alles, was ihr tun müsst, damit all eure CSS-Dateien wesentlich kleiner sind und eure Nutzer somit eine geringere Ladezeit aufgrund der geringeren Dateigröße erreichen. Und eine schnellere Website hat zufriedenere Nutzer und somit auch mehr dauerhafte Nutzer zur Folge. Somit sollte es euch Wert sein ein paar Minuten Zeit in eine solche Optimierung zu stecken.
Kommentare laden