Ankündigung

Einklappen
Keine Ankündigung bisher.

Speed Optimierung für OpenWeatherMap per Header

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Speed Optimierung für OpenWeatherMap per Header

    Für ein Hobbyprojekt wurde eine Wetterprognose auf Basis der Openweathermap-API erstellt.
    Die von der API gelieferten Informationen werden serverseitig für die Zeit $maxCacheTime in einer Cache-Datei gespeichert.
    Erst wenn die Cache-Datei älter als $maxCacheTime ist, wird die API erneut angesprochen. Soweit zum Hintergrund.

    Die Idee ist jetzt, per PHP-Header den Browsercache soweit zu bringen, bis zum erneuten Ansprechen der API die Informationen komplett aus dem Cache zu holen.
    Dazu nutze ich aktuell folgenden Code:

    PHP-Code:
    $lastModify dt::create($cacheFileTimeStamp,'GMT');
    $expires dt::create($lastModify)->modify($maxCacheTime);
    $maxAgeSec Max(dt::create('now')->diff_total($expires,'Sec'), 0);

    header("Last-Modified: " $lastModify->format('D, d M Y H:i:s','en') .' GMT');
    header('Expires: ' $expires->format('D, d M Y H:i:s','en') . ' GMT');
    header("Cache-Control: public, max-age=" $maxAgeSec); 
    Last-Modified wird auf die Zeit der letzten Änderung des Cachefiles gesetzt.
    Die dafür genutzte Klasse dt ist eine Erweiterung für DateTime. Ich hoffe,
    es ist auch ohne große Klassenbeschreibung ersichtlich was gemacht wird.

    Anmerkung zu Last-Modified:
    Im Web kursiert viel folgender Code (z.B. hier)
    PHP-Code:
    $mod_gmt gmdate("D, d M Y H:i:s"getlastmod()) ." GMT";
    header("Last-Modified: " $mod_gmt); 
    Da PHP überwiegend dynamischen Content erzeugt, führen die obigen Zeilen dazu das der Nutzer fast immer alten Inhalt zu sehen bekommt,
    da getlastmod() die Zeit der letzten Änderung des auseführten Skripts liefert! (Bin auch darauf reingefallen ).

    Expires wird auf die frühest mögliche Zeit gesetzt zu der die API erneut angesprochen wird und max-age wird auf die Sekundenzahl bis zu Expires gesetzt.

    Dies funktioniert soweit ganz gut.
    Beim ersten Zugriff liefert html bei einem API-zugriff ein Status 200 (Ok) mit Zeiten von 0,5..1,5 Sekunden, ohne API-Zugriff bei 0,4 Sekunden.
    Die folgenden Zugriffe mit Status 304 (not Modified) liegen dann unter 0,2 Sekunden.

    Nun endlich zum Problem:
    Den obigen Code wollte ich erweitern mit einem sog. ETag-Header:
    PHP-Code:
    header('ETag: "' md5($htmlContent) . '"'); 
    Wenn die Wetter-API erneut angesprochen wird, müssen nicht unbedingt neue Informationen vorliegen.
    Der ETag sollte dafür sorgen, daß nur bei echt neuen Informationen diese geholt werden.
    Die Wirkung vom ETag ist jedoch nicht wie erhofft. Bei einem konstanten ETag wird mit jeder Anfrage der Server angesprochen, der jedesmal mit 200 (Ok) bei Zeiten von 0,4 Sekunden antwortet.

    Hab ich nun noch ein Verständnisproblem zum ETag oder liege ich mit meiner obigen Variante schon richtig?

    LG jspit

  • #2
    Wenn du etag verwendest musst du den selbst prüfen und entsprechend ein 200 oder 304 zurückgeben.

    PHP-Code:
    $etag etag für aktuelle version erzeugen;

    if(
    $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
        
    header('HTTP/1.1 304');
        exit;
    }

    header('etag...')
    //neuen content an client schicken 
    Vorteil dabei ist die Daten sind immer aktuell. Nachteil ist du hast immer den Request. Das selbe Spiel hast du auch bei Last-Modified.

    Wenn du den kompletten Request einsparen willst musst du Expires nehmen, da fragt der Client erst nach diesen Zeitpunkt wieder an und das ggf. mit Last-Modified.

    Welche Caching Methode der Browser nimmt hängt vom Browser ab. Ich glaube so die Standardreihnfolge ist etag, expries, last-modified.

    Kommentar


    • #3
      Dann ist der ETag für den Browser nur ein Durchläufer, welcher als If-None-Match gespiegelt wird und auf das Cacheverhalten des Browsers gar kein Einfluss hat?
      Wenn umfangreicher Inhalt vom Server geliefert wird, ergeben sich bestimmt sinnvolle Anwendungen dafür.
      Für meinen speziellen Fall ist der Umfang jedoch zu klein, so das ich wohl auf das ETag verzichten werde.
      Deine Antwort klärt mein Problemchen, Danke.

      Kommentar

      Lädt...
      X