2009-07-21 7 views
7

J'ai quelques tutoriels sur la façon de gzip un fichier css dans lequel vous créez un fichier php public pour inclure des fichiers CSS avec compression. Le problème est que je ne peux pas l'obtenir pour mettre en cache mes fichiers CSS. J'utilise firebug comme référence et j'ai effectivement essayé d'utiliser le même code pour compresser du javascript et ça se met bien en mémoire cache.Caching gzipped css

Voici le code:

 
if(extension_loaded('zlib')){ 
ob_start('ob_gzhandler'); 
} 
$offset = 60 * 60 * 24 * 31; 
header('Content-type: text/css'); 
header ('Cache-Control: max-age=' . $offset . ', must-revalidate'); 
header ('Expires: ' . gmdate ("D, d M Y H:i:s", time() + $offset) . ' GMT'); 
ob_start("compress"); 
function compress($buffer) { 
    // Remove Comments, White Space, End ;'s 
    $buffer = preg_replace('#/\*.*?\*/#s', '', $buffer); 
    $buffer = preg_replace('/\s*([{}|:;,])\s+/', '$1', $buffer); 
    $buffer = preg_replace('/\s\s+(.*)/', '$1', $buffer); 
    $buffer = str_replace(';}', '}', $buffer); 
    $buffer = str_replace(' {', '{', $buffer); 
    return $buffer; 
    } 

    include('global.css'); 

    if(extension_loaded('zlib')){ 
    ob_end_flush(); 
} 

Je suis simplement référence à mon fichier php en tant que document de css sur d'autres pages. Comme vous pouvez le voir j'ai essayé d'ajouter l'âge maximum au mélange qui s'avère également infructueux.

Voici les en-têtes de réponse

 
Date  
Tue, 21 Jul 2009 19:59:19 GMT 

Server 
Apache/1.3.41 (Darwin) PHP/4.4.9 

X-Powered-By  
PHP/4.4.9 

Cache-Control 
max-age=2592000, must-revalidate 

Expires 
Thu, 20 Aug 2009 19:59:19 GMT 

Content-Encoding  
gzip 

Vary  
Accept-Encoding 

Keep-Alive 
timeout=15, max=93 

Connection 
Keep-Alive 

Transfer-Encoding 
chunked 

Content-Type  
text/css 

Y at-il quelque chose que je suis absent, ou une meilleure façon de s'y prendre pour le faire?

Merci,

EDIT:

Un script qui détecte si oui ou non le fichier a été modifié & l'envoi d'un 304 si elle n'a pas, en combinaison avec les en-têtes appropriés a résolu ce problème.

Arthur

Répondre

7

Essayez d'ajouter ceci à l'ensemble des en-têtes: -

$offset = 60 * 60 * 24; 
header('Content-type: text/css'); 
header('Cache-Control: max-age=' . $offset); 
header('Expires: ' . gmdate ("D, d M Y H:i:s", time() + $offset) . ' GMT'); 
header('Last-Modified: ' . gmdate ("D, d M Y H:i:s", time()) . ' GMT'); 

Le problème était l'instruction must-revalidate dans l'en-tête de contrôle du cache. Cela obligerait le client à re-demander le CSS chaque fois que cela est nécessaire et votre code ne gère pas l'en-tête If-Modified-Since et l'envoi d'un code d'état de réponse non modifié.

L'approche ci-dessus réduit la période de cache à 1 jour et élimine l'instruction de revalidation obligatoire. Il ajoute également l'en-tête Last-Modified (un cache peut choisir de ne pas mettre en cache un élément quand un en-tête Last-Modified ou ETag est manquant).

Pour améliorer cela, vous pouvez trouver la dernière heure réellement modifiée du fichier css que vous compressez et l'envoyer comme en-tête Last-Modified. Vous pouvez inclure dans votre code une comparaison des requêtes If-Modified-Since entête avec la valeur des fichiers css dernière modification. Si vous les trouvez identiques envoyez cet ensemble d'en-têtes mais envoyez aussi un état non modifié à 304 et n'envoyez pas le corps du tout. (Je ne suis pas vraiment une personne PHP donc je vais laisser ça aux experts PHP pour placer une autre réponse). Effectuez une évaluation réaliste de la durée pendant laquelle vous souhaitez qu'un client mette en cache le fichier css avant d'effectuer une autre tentative pour le récupérer et définir la valeur max-age en conséquence.

+0

Hey Anthony, J'ai essayé d'ajouter Last-Modified comme vous l'avez suggéré avec la combinaison d'une date de modification ultérieure et précédente sans chance. J'ai aussi envoyé des en-têtes avec un ETag & Si modifié depuis, et il n'est toujours pas en cache ... Merci pour votre réponse, je garderai tout cela à l'esprit pour les futures références et le débogage. – askon

+0

@askon: Ce n'étaient pas les facteurs critiques, le problème clé est l'inclusion de la directive must-revalidate dans l'en-tête Cache-Control. En utilisant cela, le CSS sera toujours récupéré. Aussi utilisez-vous l'actualisation de la page (F5) dans vos tests? Cela ne prouvera rien, des ressources telles que css sont récupérées dans un contexte d'actualisation et sans un mécanisme 304 intégré dans votre code qui va aboutir à une extraction complète de la ressource. – AnthonyWJones

+0

Désolé, j'aurais dû être un peu plus spécifique. j'ai fait enlever la ligne doit revalider, voici ma réponse d'en-tête: http://freetexthost.com/zqbddbchvz Ce que je ne comprends pas, je peux essayer le même script exact, sauf sur un texte/javascript document et il montre un 200 & cache. – askon

-1

Si vous lisez python/django, vous pouvez lire le code pour django compressor. Il met plusieurs fichiers CSS en un seul. La partie CSS ressemble à CSSTidy pour nettoyer le CSS.

+0

2014-12-03: Hé, @downvoter, merci d'être passé et de donner votre avis sur une réponse de 5 ans et demi. – hughdbrown