Seite 1 von 2

CSS Gzip Browserunterstützung

Verfasst: 07.04.2010, 10:07
von marc77
Hallo,

bin gerade bei meine css files zu komprimieren. Ich kenne eigentlich alle methoden (mod_deflate, htaccess, direkt in die css und in php umbenennen usw.).

Ich habe mich trotzallem für die einfachste aber für mich effektivste Methode entschieden. Ich schreibe einfach

Code: Alles auswählen

if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
header('Content-type: text/css');
ob_start("ob_gzhandler");
in die css datei ganz oben und benenne Sie in php um.

Frage: Ist die Browserunterstützung bei allen Browsern aufgrund der Umbenennung trotzdem gegeben? ich möchte eigentlich ungern auf das Caching durch den Browser verzichten auch wenn ich durch die komprimierung einiges einspare sollte die datei nicht dauerhaft ausgeliefert werden nur weil Sie jetzt php und nicht css heisst.
Ich denke durch
header('Content-type: text/css');
sagt man dem browser das es eine css datei ist und er behandelt die php datei dann wie eine css aber ich bin mir nicht sicher.

danke für eine Rückmeldung!

Verfasst:
von
Content Erstellung von ABAKUS Internet Marketing
Ihre Vorteile:
  • einzigartige Texte
  • suchmaschinenoptimierte Inhalte
  • eine sinnvolle Content-Strategie
  • Beratung und Umsetzung
Jetzt anfragen: 0511 / 300325-0

Verfasst: 07.04.2010, 10:47
von Synonym
Also das ist wohl eher ein Thema für Mork, aber so würde ich das jedenfalls nicht machen. Habe nur schlechte Erfahrungen mit dynamischen CSS-Files, bzw. CSS-Files, die PHP-Scripte sind.

Ich überlasse das dem Apache immer direkt per mod_deflate und das File bleibt eine .css. So weit ich weiß geht das Komprimieren so zwar schon, aber dank der .php geht das Caching verloren.

Kann mich da aber auch irren :wink:

Re: CSS Gzip Browserunterstützung

Verfasst: 07.04.2010, 10:47
von Mork vom Ork
marc77 hat geschrieben:

Code: Alles auswählen

if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) {
header('Content-type: text/css');
ob_start("ob_gzhandler");
in die css datei ganz oben und benenne Sie in php um.

Frage: Ist die Browserunterstützung bei allen Browsern aufgrund der Umbenennung trotzdem gegeben?
Eine (vermeintliche) Dateiendung ist und war nie von Bedeutung für die Behandlung des Inhalts durch Browser. Was zählt, ist einzig das, was im Kopf der HTTP-Antwort steht.
Ich denke durch
header('Content-type: text/css');
sagt man dem browser das es eine css datei ist und er behandelt die php-datei
Beim Browser kommt kein PHP an. PHP ist eine serverseitige Sprache, ein PHP-Skript wird vom Webserver bzw. dem PHP-Interpreter auf dem Server verarbeitet und nur das, was das Skript ausgibt, wird an den Browser gesendet.
ich möchte eigentlich ungern auf das Caching durch den Browser verzichten
Effektives Caching hast du alleine dadurch abgewürgt, dass dein Skript den bei jedem Webserver von Haus aus für statische Dateien wunderbar funktionierenden Mechanismus der bedingten HTTP-Anfragen nicht unterstützt. Anders gesagt: Du hast die Situation verschlimmbessert, statt nichts sendest du jetzt komprimierte Daten.

Objekte, denen kein Verfallsdatum mitgegeben wurde, werden grundsätzlich bei jeder Verwendung vom Browser neu beim Server angefragt, ausdrücklich auch, wenn der Browser das Objekt schon im Cache hat. Er macht dann allerdings eine bedingte Abfrage, d.h. er fragt nach, ob sich das Objekt seit seiner letzten Anfrage geändert hat. Ist dem so, antwortet der Server nur mit einem knappen "Nicht geändert", anstatt den ganzen Kram nochmals zu schicken.
Diesen Mechanismus unterstützt dein Skript nicht – und bevor du auf die Idee kommst: Es ist Unsinn, sowas einzubauen, weil dein Webserver das ganz alleine kann, du musst eigentlich nur nichts tun.

- Lege statische Daten grundsätzlich als statische Datei ab. Der Webserver übernimmt die Behandlung bedingter Anfragen ohne weiteres Zutun komplett.
- Für Daten, die sich eher nicht bei jedem Aufruf ändern, sende ein Verfallsdatum (zB mittels ExpiresByType), und sei es mit einem Verfall in wenigen Stunden. Alleine damit vermeidest du haufenweise wiederholte Anfragen, einschließlich bedingter.
- Ist mod_deflate o.ä. vorhanden, aktiviere es.
- Ist mod_deflate nicht vorhanden oder hast du Dateien, die sich sehr selten ändern, komprimiere die Datei von Hand mittels gzip. Benenne das Original in beispiel.css.css (doppelte Endung!) um und die komprimierte Fassung in beispiel.css.gz, belasse Verweise auf diese Datei aber beim alten beispiel.css (einfache Endung!); dann füge die Zeile Options +multiviews in eine zuständige .htaccess ein. Der Apache sucht sich bei dieser Konstellation die zur Anfrage passende Datei selbständig.

Verfasst:
von

Verfasst: 07.04.2010, 11:49
von marc77
Hallo,

danke für Deine ausführliche Antwort. Ich bin jetzt etwas verunsichert. An sovielen Stellen im web liest man von dieser Methode und nun ist sie komplett falsch. ok, ich baue Sie wieder aus. mod deflate habe ich nicht, da ich apache 1 habe und mod deflate erst ab apache 2..ich hab also mod gzip.

Durch das senden in gzip hat mir mein firebug angezeigt, dass ich 80% kb gespart habe, warum ist genau eine verschlimmbesserung eingetreten?!

Mal unabhängig von der css datei, haben meine Seiten haben alle gzip in form von ob_start("ob_gzhandler"); aktiv, soll ich das also überall abschalten?

Verfasst: 07.04.2010, 12:04
von Nullpointer
du sparst zwar 80% aber die 20% werden jedes mal gesendet. bei verwendung eines verfallsdatum wird halt nur einmal pro client gesendet, also bei folgeabrufen 0%.

Verfasst: 07.04.2010, 12:08
von Synonym
Oder er kombiniert beides, dann wird komprimiert gesendet (wenn möglich) oder gar nicht ;-)

Wenn ich mich nicht irre, dann...
ob_gzhandler : Kompression durch PHP
mod_gzip : Kompression durch Apache-Modul (org. GZIP-Algo) bis v1.3
mod_deflate : Kompression durch Apache-Modul (Apache eigener Algo) ab v2.0

Ob mod_gzip oder mod_deflate ist eigentlich egal. Nur die Config unterscheidet sich voneinander.

ob_gzhandler wäre dann also nur da sinnvoll, wo es weder mod_gzip, noch mod_deflate gibt.

Verfasst: 07.04.2010, 12:17
von marc77
@Nullpointer:

wurde das verfalldatum vorher etwa gesendet als die datei noch eine *.css war? ich denke nein oder? oder wird bei css immer ein verfallsdatum gesetzt. Somit wäre es ja schon eine Verbesserung nur halt nicht die optimalste?!

Wenn eine css ein Verfallsdatum hat, wird dann die css wenn ich was ändere erst nach z.b. einer Stunde wieder beim user ersetzt? das wäre ja ungünstig oder?

@Synonym: danke für deine Unterstützung. Ich habe also apache 1 und demnach mod_gzip. Meine php Seiten lasse ich alle per ob_start("ob_gzhandler"); umschreiben. Da mir google nun gesagt hat, ich sollte meine css + js dateien auch noch gzippen, dachte ich mir ok, lese zu dem thema ein bisschen.

Ich hab nun 5 Varianten gelesen. Einmal die welche ich nutze, dann dem Server sagen er soll css dateien z.b. als php dateien sehen, dann müsste man die css nicht umbennen. Dann eine php datei vor die css schalten, oder selbst eine gz erstellen und per htaccess auswählen lassen was er nehmen soll oder die variante mit mod_gzip, da wird dann wohl on the fly umgewandelt?!

Welche Variante ist für meine Belange (apache 1) am besten? Ich denke von Hand die gz erstellen, dann müsste ich das aber immer machen wenn ich an der css was ändere?! Das mit dem Verfallsdatum leuchtet ein...ich will eigentlich einen guten Kompromiss...aber jetzt hab ich den Überblick verloren :roll:

Ich denke mod_gzip in der htaccess (on the fly) mit Ablaufdatum wäre am besten? wie soll das praktisch aussehen..evtl. hast ja einen code oder link zur hand. Danke!

Verfasst: 07.04.2010, 13:25
von Nullpointer
ja, mod_gzip aktivieren -> siehe google und dazu das "verfallsdatum" setzen -> siehe google ist in deinem fall die ideale lösung.

bei yslow und dem google tool hast du imho auch direkt erklärungen bzw. verlinkung zu hilfeseiten. du solltest dir das gründlich anschauen, damit es ordentlich konfiguriert ist.

Verfasst: 07.04.2010, 13:44
von marc77
Leider finde ich mit verfallsdatum setzen keine wirklichen Infos. Macht ihr das alle? Wenn ich dann aber etwas geändert habt und beim user liegt eine datei die sagt, ändere mich erst in z.b einer Stunde, dann sieht er erst in einer Stunde die Änderungen korrekt? Kann ich dann noch irgendwie das Verfallsdatum für den user beinflussen?! Ich verändere z.b. eine css einstellung wegen einem bild, wenn der user dann die seite aufruft, passt das css für ihn ja nicht mehr, er bekommt also die seite falsch dargestellt. f5 hilft in dem fall nicht..habs grad getestet..hat nur geholfen den cache zu löschen..mmhhh

Du meinst also so:

Code: Alles auswählen

< ?php   
ob_start &#40;"ob_gzhandler"&#41;;   
header&#40;"Content-type&#58; text/css; charset&#58; UTF-8"&#41;;   
header&#40;"Cache-Control&#58; must-revalidate"&#41;;   
$offset = 60 * 60 ;   
$ExpStr = "Expires&#58; " .   
gmdate&#40;"D, d M Y H&#58;i&#58;s",   
time&#40;&#41; + $offset&#41; . " GMT";   
header&#40;$ExpStr&#41;;   
?>  

Verfasst: 07.04.2010, 13:53
von Synonym
wie Mork schon geschrieben hatte, damit:
https://httpsd.apache.org/docs/1.3/mod/mod_expires.html

allerdings... ab Apache1.2. Hast Du wirklich noch einen 1.0 ?? Wäre ja fast schon grob fahrlässig...

Verfasst: 07.04.2010, 14:06
von Nullpointer
Das ist die Kehrseite des Verfallsdatums. Bei vielen Dateien wird es keinen Unterschied machen, ob die jetzt eine Stunde früher oder später aktualisiert werden. Bei Scripten kann das ganz anders aussehen.
Da arbeite ich mit Versionsnummern. Habe also ein Verfallsdatum in weiter Zukunft und das Script wird mit einer Versionsnummer versehen -> foo-1_3_2.js
Wenn das Script geändert wird, ändert sich auch der Dateiname. Das ist bei mir im Buildscript festgelegt. Dadurch werden sofort nach dem Deployment die alten Scripte obsolet.

Verfasst: 07.04.2010, 14:15
von Synonym
Da arbeite ich mit Versionsnummern
Ich auch. Hat sogar noch den Vorteil, dass man die alten Versionen noch hat und notfalls wieder zurück kann, wenn man denn etwas kaputt optimiert haben sollte ;-)

Verfasst: 07.04.2010, 15:05
von marc77
kann ich mit mod_gzip nicht das gleiche machen wie mit mod_deflate und wenn ja, hat vielleicht jemand ne seite zur hand...?!

Verfasst: 07.04.2010, 15:57
von Mork vom Ork
marc77 hat geschrieben:An sovielen Stellen im web liest man von dieser Methode und nun ist sie komplett falsch.
Sie ist für deinen Einsatzfall, eine statische Datei, falsch, weil du damit einen anderen, im Server eingebauten Mechanismus aushebelst und ihn im Skript selbst nicht übernimmst.

Hättest du ein Skript, wäre sie durchaus richtig (mit Skript meine ich etwas, was Programmlogik erfordert, du hast ja nur ein Skript, weil du ob_Dingens verwenden wolltest) – aber noch nicht der Weisheit letzter Schluss, denn am wenigsten Umstände verursacht die transparente Komprimierung durch den Server, also mit mod_deflate bzw. mod_gzip.
Durch das senden in gzip hat mir mein firebug angezeigt, dass ich 80% kb gespart habe, warum ist genau eine verschlimmbesserung eingetreten?!
Weil du, grob gesagt, das Nicht-Senden durch das Senden von komprimierten Daten ersetzt hast. Anstatt einen Gutteil Anfragen mit "Nicht geändert" und 0 Bytes Daten zu beantworten, beantwortest du jetzt jede Anfrage mit 1/5 der tatsächlichen Datenmenge, was zwar weniger als 100% ist, aber immer noch mehr als 0. Du hast quasi den Kofferraum entrümpelt, aber schleppst jetzt ständig einen Anhänger hinter dir her – weniger Benzin verbrauchst du auf die Weise nicht unbedingt.

Am sinnvollsten ist der Einsatz beider Techniken.
Mal unabhängig von der css datei, haben meine Seiten haben alle gzip in form von ob_start("ob_gzhandler"); aktiv, soll ich das also überall abschalten?
Wenn deine Seiten alle PHP benötigen (im Sinne von besagter Programmlogik), kannst du das zwar drin lassen, aber es wäre wesentlich klüger, einfach mod_gzip einzusetzen, wenn's denn schon da ist. Damit hältst du den Komprimierungskram aus deinen Skripten raus und die Komprimierung wird auf alle (Text-) Dateien ausgedehnt, egal ob HTML, CSS oder Javascript, selbst auf die robots.txt – das bekommst du alles mit einer einmaligen Aktivierung (anstatt jede Datei einzeln mit ob_Dings zu versorgen).
ich hab also mod gzip
Das ist genauso gut wie mod_deflate, schalte es ein. Beide basieren IIRC auf derselben Bibliothek, mod_deflate ist lediglich an die internen Apache-2-Strukturen angepasst, mod_gzip an jene des Apache 1.

Eine deutsche Anleitung findest du unter https://schroepl.net/projekte/mod_gzip/config.htm

[Verfallsdatum]
Wenn ich dann aber etwas geändert habe und beim user liegt eine datei die sagt, ändere mich erst in z.b einer Stunde, dann sieht er erst in einer Stunde die Änderungen korrekt?
Theoretisch ja (praktisch hängt das von den Browsereinstellungen ab, aber die kannst du eh nicht beeinflussen).

Die Anleitung für ExpiresByType beim Apache 1.3 findest du unter https://httpsd.apache.org/docs/1.3/mod/ ... iresbytype, sie ist auch nicht schwer zu verstehen, es sei denn, du kannst nullkommagarkein Englisch.
Ich verändere z.b. eine css einstellung wegen einem bild, wenn der user dann die seite aufruft, passt das css für ihn ja nicht mehr, er bekommt also die seite falsch dargestellt.
Das ist der Nachteil eines Verfallsdatums. Ob das wirklich dramatisch ist, muss jeder für sich selbst entscheiden; wer möchte, kann mit sich ändernden URLs arbeiten (die vorgeschlagene Versionsnummer im Dateinamen).

Code: Alles auswählen

header&#40;"Content-type&#58; text/css; charset&#58; UTF-8"&#41;;
Unabhängig vom Thema: Diese Zeile ist falsch, Attribute werden mit Gleichheitszeichen belegt, also text/css; charset=utf-8

Code: Alles auswählen

header&#40;"Cache-Control&#58; must-revalidate"&#41;;   
$offset = 60 * 60 ;   
$ExpStr = "Expires&#58; "
Das ist ein Widerspruch. Erst verlangst du mit must-revalidate, dass der Browser bei jeder Verwendung das Objekt mit dem Server abgleichen muss, dann setzt du mit Expires ein Verfallsdatum, welches besagt, dass der Browser das Objekt bis zum Verfall nicht mehr prüfen braucht.

Verfasst: 08.04.2010, 08:46
von marc77
Hallo Mork,

danke für deine Mühen. Habs jetzt fast verstanden und werde bald apache2 am start haben. Hätte aber noch eine Verständnisfrage, nach dem ich mir das alles hier mehrmals durchgelesen habe. Du schreibst:

--
Weil du, grob gesagt, das Nicht-Senden durch das Senden von komprimierten Daten ersetzt hast. Anstatt einen Gutteil Anfragen mit "Nicht geändert" und 0 Bytes Daten zu beantworten, beantwortest du jetzt jede Anfrage mit 1/5 der tatsächlichen Datenmenge, was zwar weniger als 100% ist, aber immer noch mehr als 0.
--

Frage: Warum wird bei komprimierten Daten immer gesendet und diese nicht auch mit "nicht geändert" beantwortet. Diese komprimierten Daten liegen doch auch wie die unkomprimierten im Temporary Internet Files Ordner und haben kein Verfallsdatum also müsste hier doch auch "nicht geändert" ausgeben werden...?