Dateien mit .htaccess gzip komprimieren

Oktober 2009

Mit Hilfe der .htaccess-Datei und PHP kann man beliebige Dateien einer Website mit gzip komprimieren.
Da Prinzip ist recht simpel: Wenn eine bestimmte Datei auf dem Server angefordert wird, fügt ihr die .htaccess eine PHP-Datei vorne an, welche das gzip-Handling übernimmt.

Der benötigte Code für die .htaccess-Datei:
<FilesMatch "^(dateiA\.php|dateiB\.html|dateiC\.css)$">
 SetHandler application/x-httpd-php     # Die Dateien müssen mit PHP geparst werden
 php_value auto_prepend_file ./gzip.php # PHP soll die Datei "gzip.php" vorne anfügen
</FilesMatch>

Und der Inhalt der Datei gzip.php:
<?php
ob_start
('ob_gzhandler');
?>

Wenn nun beispielsweise die Datei dateiC.css aufgerufen wird, muss diese zuerst durch den PHP-Interpreter. PHP fügt aufgrund der Direktive auto_prepend_file die Datei gzip.php an den Anfang der Datei dateiC.css hinzu und führt diese aus.
Durch die Funktion ob_start() wird die Ausgabe der Datei zurückgehalten und mittels der Callback-Funktion ob_gzhandler() wird die Ausgabe dann gzip komprimiert.

Anmerkungen:
Wenn der Client (Browser) kein gzip unterstützt, wird die Datei unkomprimiert ausgegeben.
Falls XML-Dateien komprimiert werden sollen, muss darauf geachtet werden, dass die XML-Deklaration <?xml..?> nicht fälschlicherweise als PHP-Shorttag interpretiert wird, was zu einer fehlerhaften Ausgabe führen kann.
Wichtig: Diese Methode funktioniert nicht, falls PHP als CGI-Programm läuft.


Eine andere Methode, die gzip-Komprimierung anzuwenden, ist das direkte Speichern der Datei als gzip. Die Datei liegt in diesem Falle in der unkomprimierten und der komprimierten Version vor, ist also quasi doppelt vorhanden. Da der Server die Datei dadurch nicht mehr on-the-fly komprimieren muss, ist diese Methode ressourcensparender. Allerdings funktioniert es wiederum nur mit statischen Dateien, also keine PHP-generierten Seiten, etc.
Eine Möglichkeit die Dateien zu komprimieren, wäre folgende:
<?php
$file 
'beispiel.css';
$content file_get_contents($file); // Datei öffnen
$content gzencode($content); // Inhalt komprimieren
file_put_contents($file.'.gz'$content); // Datei speichern
?>
Die Datei wird in diesem Falle als gz-Datei abgespeichert, also wird beispielsweise aus "style.css" "style.css.gz".
Wer es nicht mit PHP machen kann oder will, kann eine lokale Software nutzen oder das Tool CodeCompressor verwenden, um die Datei zu komprimieren.
Was nun noch fehlt, ist die Browserweiche, bzw. die Unterscheidung von Benutzern, welche gzip unterstützen und welche nicht. Dazu reicht folgende .htaccess:
RewriteEngine on
RewriteCond %{HTTP:Accept-encoding} gzip # Nur, wenn der Browser gzip unterstützt
RewriteCond %{REQUEST_FILENAME}.gz -f # Nur, wenn die komprimierte Version der Datei existiert
RewriteRule ^(.*)$ $1.gz [L] # Auf DateiName.gz zugreifen
AddEncoding "x-gzip" .gz # Content-Encoding angeben
<FilesMatch "\.css\.gz$"> # betrifft alle komprimierten CSS-Dateien
 AddType "text/css" .gz # Content-Type angeben
</FilesMatch>
<FilesMatch "\.html\.gz$"> # betrifft alle komprimierten HTML-Dateien
 AddType "text/html" .gz # Content-Type angeben
</FilesMatch>
# weitere FilesMatch auch für .js-Dateien, etc...
Wenn nun ein Benutzer eine Datei aufruft, von welcher es eine komprimierte Version gibt, dann bekommt dieser Benutzer die komprimierte Version, sofern er gzip akzeptiert.


Tipps:
  • Bilder (PNG, JPG, etc.) sollten nicht komprimiert werden, da es keinen Vorteil in der Dateigrösse bringt oder gar kontraproduktiv sein kann.
  • Dateien (CSS, JS, etc.), welche kleiner als 200 Bytes sind, sollten aus demselben Grund ebenfalls nicht komprimiert werden.
  • Zum Prüfen, was die gzip-Komprimierung bringt, kannst du dieses Tool benutzen.

Siehe auch:
 


Andere Einträge


Kommentare

#1
von Joachim am 20.12.2009
Hallo zusammen,
ist es den auch möglich nach komprimieren mit mod_deflate.c in der htaccess
<IfModule mod_deflate.c>
<FilesMatch "\.(css|js|xhtml|html|htm|php)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
diese komprimierten Dateien in einem cache zu speichern ?
Viele Grüße Joachim

#2
von Floern am 21.12.2009
Salü,
meines Wissens lassen sich mit mod_deflate komprimierte Dateien nicht (zwischen-)speichern, da das Modul die Dateien on-the-fly komprimiert. Ich habe bisher noch nichts gelesen, dass das möglich wäre.

#3
von Gert am 31.12.2010
Hallo Floern
Ich bin verzweifelt. Wo ist der Fehler?
RewriteEngine On
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [L]
AddEncoding "x-gzip" .gz
<FilesMatch "\.css\.gz$">
AddType "text/css" .gz
</FilesMatch>
<FilesMatch "\.html\.gz$">
AddType "text/html" .gz
</FilesMatch>
--> ERROR404 ??? Wenn ich .../index.html.gz geht es.
Danke im Voraus, Gert

#4
von Gert am 01.01.2011
Hallo Floern - Nachtrag
Ich habe RewriteBase / eingefügt und bekomme nicht mehr ERROR404. In meinem browser wird mit Firebug bei YSlow und PageSpeed immer noch gesagt, dass keine komprimierten Daten vorhanden seien. Mit deinem TrafficScanner funktioniert es (Habe index.html.gz wieder gelöscht, da Seitenreport meckert = 0% und Content zu Quelltext falsch berechnet).
Gert

#5
von Rollo am 03.03.2011
Deinen Beitrag habe ich als Anregung genommen um meine CSS zu optimieren. Da ich einige technischen Probleme mit meinem Server hatte, habe ich die folgende Version genutzt:
- CSS als PHP gespeichert
- htaccess um php_value output_handler ob_gzhandler erweitert
- fertig
Klappt und die CSS wird als komptimiert in Pagespeed dargestellt.
Danke