кэширование CSS и Javascript - PullRequest
       19

кэширование CSS и Javascript

4 голосов
/ 04 августа 2011

У меня проблемы с кэшированием ...

Я использую этот php-файл с переписыванием URL для сжатия и кэширования css и js

У меня сложилось впечатление, что если я изменю / обновлю один из моих файлов, браузер получит обновленный файл. Но это не так, если я не очищу кеш или не обновлю страницу.

Правильно ли написано мое кодирование? Или браузер не предполагает получать обновленный контент до истечения срока действия кэша?

<?php
$file = $_SERVER['DOCUMENT_ROOT'].'/'.$_GET['file'];
$last_modified_time = filemtime($file);
$etag = md5_file($file);
$expires = 60*60*24*7;

if(file_exists($file))
{
    if($_SERVER['HTTP_IF_NONE_MATCH'] != $etag)
    {   
        header("Pragma: public");
        header("Cache-Control: maxage=$expires, must-revalidate");
        header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
        header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
        header("Etag: \"{$etag}\"");

        if($_GET['type'] == 'js')  header('Content-type: application/javascript');
        if($_GET['type'] == 'css') header('Content-type: text/css');
        if($_GET['type'] == 'ico') header('Content-type: image/x-icon');

        ob_start("ob_gzhandler");       
        include($file);     
    }
    else {

        header('HTTP/1.0 304 Not Modified');
    }
}
else {

    header("HTTP/1.0 404 Not Found");
}
?>

переписать правила

RewriteRule ^(.*).js$ /compress.php?file=$1.js&type=js [L,QSA]
RewriteRule ^(.*).css$ /compress.php?file=$1.css&type=css [L,QSA]
RewriteRule ^(.*).ico$ /compress.php?file=$1.ico&type=ico [L,QSA]    

---------

РЕДАКТИРОВАТЬ: Может быть, я должен сделать это по-другому? что большие компании используют для кэширования и как они заставляют браузеры получать обновленный контент до истечения срока действия кэша?

РЕДАКТИРОВАТЬ 2: Спасибо, парень, за помощь. Я собираюсь с 1-часовым кешем

Ответы [ 3 ]

6 голосов
/ 04 августа 2011

Браузер не обновляет кэшированные файлы, пока не истечет срок действия указанного заголовка Expires. Если срок его действия истек, он запросит файл с заголовком If-None-Match (наверное).

Но почему вы не справились с управлением кешем через .htaccess? Вы можете проверить mod_expires:

# Expires-Header
ExpiresActive On
ExpiresByType application/javascript "access plus 7 days"
ExpiresByType text/css "access plus 7 days"

# ETag
FileETag All

Gzip-сжатие, а также mod_deflate:

AddOutputFilterByType DEFLATE text/css application/javascript

Редактировать: «Большие компании» не используют заголовки Expires или max-age, или они установят эти заголовки так, чтобы файлы кэша оставались на ~ 1 час -> конфликты с кэшированием будут минимизированы. Вы устанавливаете это на 1 неделю.

1 голос
/ 04 августа 2011

Вы упускаете эту часть, я полагаю ...

    $last_modified = filemtime($file);

    // Check for cached version
    if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) OR isset($_SERVER['HTTP_IF_NONE_MATCH'])) 
    {
        // these part should do that...
        if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == gmdate('D, d M Y H:i:s \G\M\T', $last_modified)) 
        {
            header('HTTP/1.0 304 Not Modified');
            return;
        }
    }   
    header('Last-Modified : '.gmdate('D, d M Y H:i:s \G\M\T', $last_modified));
    header('Cache-Control : max-age='.$expires.', must-revalidate');
    header('Expires : '.gmdate('D, d M Y H:i:s \G\M\T', $last_modified + $expires));
    // and so on...

Кстати, за то, что вы можете гораздо больше определить, как связана производительность вашего кэша или, что еще лучше, производительность всего приложения, вы можете протестироватьэто с помощью производительности API Google, или этих сайтов: http://www.webpagetest.org/ (PS: просто для примера, это мой последний результат для моего на рабочем блоге: http://www.webpagetest.org/result/110803_SB_17PVH/)

0 голосов
/ 04 августа 2011

Да, теоретически браузер должен обращать внимание на информацию Cache-Control, Expires и т. Д., Которую вы отправляете обратно, но на практике не всегда стоит доверять браузеру правильные действия.

Что вы, возможно, захотите сделать, это добавить второй шаг в свой скрипт compress.php ... пусть он перенаправит на фактический сжатый файл и добавит что-то вроде "?ts=".$last_modified_time к пути к файлу. Таким образом, при изменении файла URL-адрес изменится, и браузер с гораздо большей вероятностью сделает все правильно и получит самый последний файл. Я использовал подобную технику раньше.

...