Hier im Forum bekommt ihr bei euren fragen schnelle hilfe.Hier geht es rund um das Web SeitenProgrammieren.Alles rund ums Javascript,Html,Php,Css und Sql.Auf fast allen Fragen haben wir eine Antwort.
Der Soforthilfe-chat verspricht das ,was sein Name sagt. Hier sind Leute Online die sofort ihre hilfe anbieten.Seht in der OnlineListe nach und wenn einer Online ist werdet ihr auch antwort bekommen. Admine ,Moderatoren und Helfer sind unsere Spezialisten in Sachen Web Programierung
71 Unwetterwarnungen in Deutschland
Die Datenbank wurde zuletzt am 02.08.2020 17:34:28 aktualiesiert
71

Optimierungen von CSS und JavaScript on-the-fly

In meinem letzten Beitrag habe ich einige M öglichkeiten aufgezeigt, wie man HTML-, CSS und JavaScript-Code verkleinern kann ohne die Darstellung und Funktionalit ät zu beeintr ächtigen. Wenn man jedoch keine Lust hat, immer nach einem Bearbeiten die Optimierungen wieder vorzunehmen, hab ich hier eine praktikablere L ösung. Au ßerdem wollen wir zus ätzlich die Komprimierung der Daten einsetzen sowie das Client-side Caching einsetzen.
Das Ziel soll also eine L ösung sein, bei der wir mit unseren wohlstrukturierten Dateien weiterarbeiten k önnen, aber trotzdem sollen m öglichst wenig Daten vom Client geladen werden m üssen.

Warum wollen wir eigentlich um jeden Preis die zu ladenden Daten so klein wie m öglich halten? Es gibt 2 Gr ünde:

Wenn wir es also schaffen, mit wenig Aufwand die Datenmenge zu verringern, k önnen wir sowohl etas f ür unsere User als auch f ür unseren Geldbeutel tun.

Zuerst schauen wir uns CSS-Dateien an. Ich habe bereits bei Projekten mitgemacht, bei denen die CSS-Datei 40 kB gro ßwar. Sch önen Gru ßan die 56k-Modem-User! Wir gehen hier nat ürlich davon aus, dass in der CSS-Datei nur wirklich genutzte Klassen und Definitionen enthalten sind –ansonsten wirkt dieser Tuningversuch l ächerlich f ür das Projekt. Gut, wir nehmen und als Beispiel eine CSS-Datei mit einer Definition f ür das DIV-HTML-Element. Nat ürlich haben wir Multiformateigenschaften genutzt, um dadurch schon mal einige Bytes zu sparen, denn dabei geht die Übersicht auf keinen Fall verloren.

div {  
     font:bold 0.9em/12px Arial;
     /* fett groesse/zeilenabstand schriftart */   
     border:solid 1px red;
     /* typ breite farbe */   background:url(images/bild.jpg) top repeat-x;
           /* url position wiederholung */
           }

           
           

Diese CSS-Datei kann nun nur noch durch 2 Dinge optimiert werden: Entfernung von Zeilenumbr üchen und Entfernen der Kommentare. Allerdings kann man mit der entstehenden 1-Zeilen-Datei sp äter kaum noch arbeiten, deshalb w äre es doch toll, wenn diese Optimierungen zwar gemacht w ürden, wir uns aber nicht darum k ümmern m üssten.
Wir brauchen demzufolge ein L ösung, die on-the-fly die optimierte CSS-Datei erstellt und an den Client schickt. Um überhaupt an der Datei etwas ändern zu k önnen, bevor sie geladen wird, brauchen wir erstmal PHP bzw. dessen Output Buffering. Dazu lassen wir unsere CSS-Datei(en) durch den PHP-Parser laufen. Das legt man über einen zus ätzlichen Eintrag in der .htaccess fest (wenn diese Datei im root ihres Webprojekts noch nicht existiert, legen sie sie einfach an).
AddType application/x-httpd-php .css
Eine andere PHP über das Stylesheet schicken zu k önnen, w äre die .css-Datei in .php umzubenennen, aber dann m üssten alle Referenzierungen in der Anwendung umgeschrieben werden.

Was tun wir nun damit? Wir packen den PHP Output Buffer mit einer eigenen Callback-Funktion in die CSS-Datei. Die Callbackfunktion wird aufgerufen, nachdem die gesamte Dateiausgabe feststeht (der eigentliche CSS-Code geladen wurde), und erh ält als Parameter genau diesen CSS-Code als String.

<?php header("Content-type: text/css"); 
ob_start("compress"); 
header ("content-type: text/javascript");
header ("cache-control: must-revalidate;max-age: 3600"); 
header ("expires: " . gmdate ("D, d M Y H:i:s", time() + 3600) . " GMT");  
function compress($buffer) {  
// remove comments   
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
// remove tabs, newlines, etc.   
$buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);
//remove multiple spaces   
$buffer = preg_replace('/\s\s+/', ' ', $buffer);  
return $buffer;
} 
?> 
div {   
font:bold 0.9em/12px Arial;
/* fett groesse/zeilenabstand schriftart */   
border:solid 1px res; 
/* typ breite farbe */   background:url(images/bild.jpg) top repeat-x; 
/* url position wiederholung */ } 
<?php ob_end_flush(); ?>

             

Die Funktion compress ist unsere Callback-Funktion. Wir bearbeiten den Buffer (den CSS-Code) durch das Entfernen von Kommentaren, Zeilenumbr üchen und Tabulatoren sowie mehrfachen Leerzeichen. Dadurch wird folgende CSS-Datei im Endeffekt wirklich an den Client geschickt:

div { 
font:bold 0.9em/12px Arial;
border:solid 1px red;
background:url(images/bild.jpg) top repeat-x;
}

Durch diese recht trivialen Änderungen konnte die urspr üngliche Gr öße von 212 Bytes auf jetzt nur noch 103 Bytes verkleinert werden. Das sind über 50% weniger Daten! Und wenn man es mit der CSS-Datei vergleicht, bevor man Multiformateigenschaften genutzt hat (wenn man diese aufl öst und alle Einzeleigenschaften aufschreibt kommt man auf 358 Bytes), betr ägt die Speicherplatzeinsparung sogar über 70%!

Mit JavaScript-Dateien k önnen wir ähnlich verfahren. Wir f ügen die Endung .js zur .htaccess hinzu, damit sie vom PHP Parser verarbeitet wird. Bei JavaScript sind die gleichen Formatierungen m öglich, nur m üssen wir zus ätzlich die einzeiligen Kommentare entfernen, da es sonst zu Problemen beim Entfernen von Zeilenumbr üchen kommen kann. Unsere Callback-Funktion sieht bei js-Dateien also so aus:

function compress($buffer) {
// remove comments   
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
$buffer = preg_replace('!//[^\n\r]*!', '', $buffer);
/*   Konstrukte wie 
var variable = {
var1:"test",     var2:function() {
doSomething();
}
}
müssen nach der letzten schließenden Klammer ein Semikolon bekommen --> funktioniert nicht   */
//$buffer = preg_replace('/var ([^=]*) = \{(([^\}]*\})*)[\n\r]+/', "var ".'$1'." = {".'$2'.";", $buffer);
// remove tabs, spaces, newlines, etc. - funktioniert nicht, weil das vorhergehende nicht funktioniert   //
$buffer = str_replace(array("\r", "\n", "\t"), "", $buffer);   
$buffer = str_replace("\t", "", $buffer);   
// multiple whitespaces   
$buffer = preg_replace('/(\n)\n+/', '$1', $buffer);   
$buffer = preg_replace('/(\n)\ +/', '$1', $buffer);

$buffer = preg_replace('/(\r)\r+/', '$1', $buffer);
$buffer = preg_replace('/(\r\n)(\r\n)+/', '$1', $buffer);   
$buffer = preg_replace('/(\ )\ +/', '$1', $buffer);   
return $buffer;
}

          
          

In JavaScript gibt es komplexe Konstrukt (welche genau, steht im Kommentar im Quellcode), die ich versuche, durch ein Semikolon zu erg änzen. Leider funktioniert das nicht richtig. Aus diesem Grund habe ich auch nicht alle Zeilenumbr üche entfernt, denn sonst kommt es da zu Fehlern. Trotzdem bringt diese Funktion einiges an eingespartem Traffic.
Bei einem von mir geschriebenen Script zur Darstellung der Tooltips auf SucheBiete.com brachte diese Ver änderung eine Einsparung von ca 20 % (Original: 3,24 kB, optimiert: 2,65 kB). Bei viel kommentierten Scripten wie beispielsweise Lightbox konnte ich sogar etwa 40 % einsparen (Original: 22,9 kB, optimiert: 13,8 kB).
Trotzdem muss ich sagen, dass es mit einigen JavaScripts Probleme gibt, beispielsweise mit der Bibliothek Prototype , da darin in Strings ‚/*‘und ‚//‘vorkommen. Man sollte also überpr üfen, ob es nach dem Einbau JavaScript-Fehlermeldungen gibt.

Wenn diese On-the-fly-Optimierungen durchgef ührt wurden, kann man die entstandenen Code dann noch als GZip senden, was die Gr öße des optimierten Codes auf ca ein Drittel zusammenpackt. Au ßerdem habe ich noch eine Cache-Control eingebaut, damit die Datei nicht jedes mal vom selben User erneut geladen wird.
F ür CSS:

             
             header("Content-type: text/css"); 
             header ("cache-control: must-revalidate; max-age: 2592000"); 
             header ("expires: " . gmdate ("D, d M Y H:i:s", time() + 2592000) . " GMT");
             ob_start("compress");
             function compress($buffer) { 
             // remove comments   
             $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);
             // remove tabs, spaces, newlines, etc.   
             $buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);   
             $buffer = preg_replace('/\s\s+/', ' ', $buffer);
             if (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'x-gzip') !== false) {
             
             header("Content-encoding:x-gzip");     $buffer = gzencode($buffer);
             } 
             elseif (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'gzip') !== false) {
             header("Content-encoding:gzip");
             $buffer = gzencode($buffer);
             }
             elseif (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'deflate') !== false) {
             header("Content-encoding:deflate");
             $buffer = gzdeflate($buffer);
             }
             header('Content-Length: ' . strlen($buffer));
             return $buffer;
             }
             

              
              
              

Entsprechend funktioniert es auch f ür JavaScript (au ßer eben mit den oben genannten Replaces). Wer eine js-Datei hat, die durch die angegebene Funktion nicht optimiert werden kann, weil dadurch Fehler entstehen, sollte zumindest gzippen . Wenn man aber nix mehr mit dem Buffer vorhat, reicht auch ob_start("ob_gzhandler "); .

Durch diese kleinen Eingriffe lassen sich also durchaus ohne viel Aufwand (Vorsicht, Untertreibung) einige Bytes an Trafficvolumen einsparen.
An die On-the-fly-Optimierung von HTML-Code traue ich mich im Moment nicht so recht ran, weil das mittlerweile nicht mehr sauber ist. Erstens haben viele Seiten nicht valides HTML und zweitens erschweren Geschichten wie Conditional Comments und vorformatierte Bereiche (z.B. in Textareas und <pre >-Abschnitten) das Optimieren.