Baba: css und js files über php scripte ausliefern

Schönes Wochenende allen.

Ich liefere CSS-, JS- und image-files über php-Scripte aus.

<link type="text/css" rel="stylesheet" href="/css/route.php/action/index.css">  
<script type="text/javascript" src="/js/route.php/action/index.js"></script>  

Die Images werden über mod-rewrite umgeschrieben:

RewriteCond %{REQUEST_FILENAME} !-f  
RewriteRule (.*)\.(gif|jpg|png|ico)$ /pic/route.php [NC,L]

Ich empfand den Seitenaufbau als langsam, weswegen ich mit Firebug auf Problemsuche ging. Ich sah, dass die routing-Scripte vergleichsweise lange brauchen.

Firebug Screenshot
Hinter der Zeilte index.css verbirgt sich /css/route.php/action/index.css
Hinter der Zeilte index.js verbirgt sich /js/route.php/action/index.css
Hinter icon.png und flyerbooker-back.png verbergen sich geroutete Bilder.
Die grünen Kästen zeigen native Ressourcen.

Es fällt auf: die css/route.php braucht viel länger als ein normales css file. Gleiches gilt für die js/route.php und die pic/route.php.
Ebenfalls fällt auf das die route.php länger braucht, als die normale index.php!!!, die definitiv eine Menge mehr macht. Das kann ja nicht sein. Diese Zeit kann ich halbieren, wenn ich die /css/route.php direkt aufrufe im Browser. Sie liegt dann bei 650ms. BTW: wenn ich ein leeres php-file aufrufe benötigt dies immer noch 600ms. Das ist also bei meinem Provider sozusagen der overhead.

Warum nun benötigen die route.php soviel länger? Da der php-Parser "angeworfen" werden muss? Das würde dann aber auch gelten, wenn ich die /css/route.php direkt aufrufe, was nicht der Fall ist. Ist es also problematisch, dass der Abstand der Requests auf die php-Ressourcen so gering ist? Beeinflusst sich da irgendetwas? Habe schon an session gedacht, die sich irgendwie stören, weiß aber nicht wie...

Was muss ich noch beachten, wenn ich css/js über php ausliefern möchte? Momentan setze ich folgende Header (für die js z.B):

$Modified = date("D, d M Y H:i:s", $Modified - date("Z"))." GMT";  
$Expires  = date("D, d M Y H:i:s", (time() + 86400))." GMT";  
$Etag     = md5_file($Content);  
  
header("Content-Type: text/javascript");  
header("Last-Modified: $Modified");  
header("Expires: $Expires");  
header("Cache-Control: public, max-age=86400, s-maxage=86400");  
header("Etag: $Etag");

Wobei $Modified zunächst die filemtime() der aktuellsten aller konsolidierten files ist und $Content der Inhalt,der dann ausgegeben wird mit echo $Content.

Noch eine Frage:
wenn ich die dd.css nehme (eine native Ressource). Diese verschwindet aus Firebug, wenn ich die Seite neulade (durch erneutes Klicken des Links zur Seite) und erscheint erst wieder, wenn ich einen vollen Reload erzeuge (F5). Kann man solches Verhalten auch in den routing scripts erzeugen? Es scheint, als würde die dd.css irgendwie "besser" gecached werden.

Ich wäre sehr dankbar für Antworten (ausser: route die Ressourcen lieber nicht). Ich werde das System irgendwann umbauen, dass die Konsolidierten files im öffentlichen Verzeichnis irgendwie temporär gespeichert werden. Es interessiert mich einfach, woran es liegt, dass es zu Verzögerungen kommt.

Vielen Dank im Voraus.

Cheers,
Baba

  1. Lieber Baba,

    es ist üblich, dynamisch erstellte Dateien zu cachen, um genau diesem Deinen Problem aus dem Weg zu gehen.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Guten Morgen.

      es ist üblich, dynamisch erstellte Dateien zu cachen, um genau diesem Deinen Problem aus dem Weg zu gehen.

      Juti, werde ich es also machen. Was ist jedoch die Erklärung? Das würde mich doch interessieren, da es ja auch an etwas anderem liegen könnte. Ich hatte zunächst nämlich auf meinen Provider getippt, dass der enorm langsam ist (Celeros). Ich hatte kürzlich auf php 5.3 umstellen lassen und seitdem viele "depracated" Warnungen, weil die es nicht hinkriegen die veralteten Schalter aus der php.ini zu nehmen, die es gar nicht mehr gibt (magic_quotes_gpc, etc). Ein Hinweis vom Support, ich könnte ja die Fehlermeldungsoptionen ändern, fand ich etwas dürftig. Können serverseitige Loggingvorgänge die Auslieferungen verlangsamen?

      Ich kann gerade nicht einschätzen, ob 600 ms für ein leeres php-Script akzeptabel ist. Warum braucht eine große JS-Ressource (300kb) nur 150ms? Auf meinem anderen Server braucht ein php-Script mit einem echo "Hello"; gerade mal 50ms.

      Und warum ist die Zeit so viel länger, wenn die Requests direkt hintereinander kommen, als wenn ich sie einzeln aufrufe. Kann ich vielleicht doch noch etwas machen.
      Das hat zwar nicht direkt damit etwas zu tun, aber ich hatte mich damals gewundert, warum meine Ajax-Requests auf php-Scripte sich gegenseitig blockieren und der Grund war, dass pro Session nur eine Verbindung zum Server bestehen durfte. Nachdem ich in jedes Script der Ajax-Requests ein session_write_close(); eintrug ging es. Ich hoffte irgendwie auf so eine Quelle... :)

      Cheers,
      Baba

      1. Hallo,

        Ich hatte kürzlich auf php 5.3 umstellen lassen und seitdem viele "depracated" Warnungen, weil die es nicht hinkriegen die veralteten Schalter aus der php.ini zu nehmen, die es gar nicht mehr gibt (magic_quotes_gpc, etc). Ein Hinweis vom Support, ich könnte ja die Fehlermeldungsoptionen ändern, fand ich etwas dürftig.

        das finde ich nicht dürftig, sondern armselig.
        "Überprüfen Sie doch bitte mal die Bremsen an meinem Auto, ich glaube, da ist was nicht in Ordnung." - "Wie wär's, wenn ich Ihnen stattdessen eine lautere Hupe einbaue?"

        Können serverseitige Loggingvorgänge die Auslieferungen verlangsamen?

        Ja, aber nicht so deutlich.

        Ich kann gerade nicht einschätzen, ob 600 ms für ein leeres php-Script akzeptabel ist. Warum braucht eine große JS-Ressource (300kb) nur 150ms?

        Du darfst nicht die Auslieferung einer JS-Ressource mit der Ausführung eines PHP-Scripts vergleichen. Im ersten Fall nimmt der Server einfach eine vorhandene Datei und wirft sie dem Client an den Kopf; im zweiten Fall muss er eventuell -je nachdem, wie PHP eingebunden ist- erst den PHP-Interpreter als Kind-Prozess starten, der muss das Script übersetzen und dann ausführen. Das kann schon deutlich länger dauern.

        Auf meinem anderen Server braucht ein php-Script mit einem echo "Hello"; gerade mal 50ms.

        Ich habe gerade angedeutet, dass die Art der PHP-Einbindung eine große Rolle spielt. Als Apache-Modul ist es "allzeit bereit", als CGI muss es jedesmal separat gestartet werden, als FCGI (Fast CGI) liegt es vom Aufwand her irgendwo dazwischen. Die Ausgabe von phpinfo() sollte dir Auskunft darüber geben (Server API).

        Und warum ist die Zeit so viel länger, wenn die Requests direkt hintereinander kommen, als wenn ich sie einzeln aufrufe. Kann ich vielleicht doch noch etwas machen.

        Das ist in der Tat eine gute Frage, auf die ich auch keine Antwort habe.

        Das hat zwar nicht direkt damit etwas zu tun, aber ich hatte mich damals gewundert, warum meine Ajax-Requests auf php-Scripte sich gegenseitig blockieren und der Grund war, dass pro Session nur eine Verbindung zum Server bestehen durfte. Nachdem ich in jedes Script der Ajax-Requests ein session_write_close(); eintrug ging es. Ich hoffte irgendwie auf so eine Quelle... :)

        Hmm, ja, es gibt aus uralten Zeiten eine Empfehlung, dass ein HTTP-Client nicht mehr als zwei gleichzeitige Verbindungen zu einem Server haben sollte. Normalerweise kann man das im Browser einstellen. Im Opera beispielsweise unter Preferences/Advanced/Network/Max. connections to a server; im Firefox finde ich die Einstellung im GUI gerade nicht. In about:config finde ich sie unter dem Schlüssel network.http.max-persistent-connections-per-server, und der Wert (default) ist 6. Eigentlich auch hoch genug, dass das hier gerade noch keinen Flaschenhals bildet - es sei denn, der Server limitiert von sich aus auch die Anzahl der gleichzeitigen Verbindungen pro Client.

        Ciao,
         Martin

        --
        If you believe in telekinesis, raise my hand.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  2. مرحبا

    » $Modified = date("D, d M Y H:i:s", $Modified - date("Z"))." GMT";  
    
    > $Expires  = date("D, d M Y H:i:s", (time() + 86400))." GMT";  
    > $Etag     = md5_file($Content);  
    >   
    > header("Content-Type: text/javascript");  
    > header("Last-Modified: $Modified");  
    > header("Expires: $Expires");  
    > header("Cache-Control: public, max-age=86400, s-maxage=86400");  
    > header("Etag: $Etag");
    
    

    Mit den Paar Zeilen kriegst du das Zeug nicht in den Cache. Minify könnte dir gefallen.

    Hinter der Zeilte index.css verbirgt sich /css/route.php/action/index.css
    Hinter der Zeilte index.js verbirgt sich /js/route.php/action/index.css

    Unterscheiden sich die einzelnen "route.php", oder routest du hier auch alles auf eine "route.php"?

    Auf meinem anderen Server braucht ein php-Script mit einem echo "Hello"; gerade mal 50ms.

    Die einen Server könnten so aussehen, die anderen so.

    mfg

    --
    <>