Heute mal wieder was Technisches, die Anforderung eine WebApp. mit großem HTML Transfer (250k) bei einem Kunden mit geringer Bandbreite zügig zum laufen zu bekommen fordert einige Optimierungen. Dinge wie Bilder in komprimierte Sprites, Gzip/Deflate Transport sind getroffen.

Problem Dynamsiche Webseite

Die Seite an sich beinhaltet Content an dem mehrere Nutzer ab und an Änderungen vornehmen. Die damit verbundenen unregelmäßigen Änderungen sind zeitlich nicht vorhersehbar und es steht auch keine “Last Modified” Information zur Verfügung. Herkömmliches Browser / Proxy Caching fällt als flach da es sonst passieren kann das ein Browser bei gezwungenem Cache den Inhalt nicht mehr aktuell präsentiert, was auf keinen Fall passieren darf.

Lösung, Dynamisches Hash-Etag

Seite ohne Cache, effektiv 30.5KB Content Der Content wird nach wie vor in seiner PHP Datei wie eh und je ohne Cache generiert. Jedoch wird statt einer direkten Ausgabe des HTML Codes selbiger als Grundlage für eine CRC Summe genommen. Diese CRC Summe dient als Etag um dem Browser zu ermöglichen eine Änderung zu identifizieren. (Was ist ein Etag ?) Der Vergleich ob wir den Content ausgeben oder nicht liegt jedoch in unserer Seite aus dem Cache, effektiv 0KB Content Serverseiten Hand. Der Client Browser übermittelt via HTTP_IF_NONE_MATCH der ihm bekannten Hash. Wir können nun vergleichen ob unser Content dem des Users entspricht, ist dies der Fall so teilen wir das dem Client mit und beenden die Verbindung ohne weitere Daten zu übertragen. Dadurch beschränkt sich die Übertragung auf die reinen HTTP Header und nicht wie vorher je Seite 250k und mehr.Das ganze mal von der Code Seite, anhand eines Beispiels, aufgezeigt:[sourcecode lang="php"] $OUT = "Mein Content"; // Es können auch andere Hash Algos verwendet werden, bei den meisten Benchmarks // ist md4 allerdings am schnellsten. Da wir hier keine Passwörter o.ä. hashen wollen // sondern quasi nur eine CRC bilden möchten ist der Algo. nicht so brisant. $hash = hash("md4",$OUT); header("Etag: $hash"); header("Cache-Control: private, must-revalidate"); if($_SERVER['HTTP_IF_NONE_MATCH'] AND $_SERVER['HTTP_IF_NONE_MATCH'] == $hash) { // Browser hat identischen Content bereits lokal header("HTTP/1.1 304 Not Modified"); // Browser mitteilen das Seite unverändert header("Connection: Close"); // Keep-Alives unterbinden exit; // Script beenden. } echo $OUT; [/sourcecode]Das hier gezeigt Script ist online zum testen des effektes am eigenen Browser unter dieser URL erreichbar.Insgesamt brachte dieses unterstützte Cachehandling einen enormen Geschwindigkeitsgewinn. Da die zu beschleunigende Seite aus über 2000 DOM Elementen besteht (250K HTML) war es bei langsamen Verbindungen somit “unschön” zu navigieren. Doch auch im kleinerem Umfeld kann dieses manuelle Tag Handling Vorteile haben. Wichtig ist das man sicherstellt das keinerlei Expire header auf die auszuliefernde Seite gesetzt ist. Denn ist dies der Fall wird primär nach Expire gegangen und erst dann anhand des eTag ein Revalidate durchgeführt.

Amazon Logo Diesen Blog unterstützen?
Bestell dir doch etwas bei Amazon. Nutze diesen speziellen Link, es kostet dich nichts extra und für jeden Kauf darüber erhalte ich eine kleine Gutschrift. Danke!
✉ Marco Götze//

Kommentare

noch 0 Einträge