Да направим оптимално кеширане с mod_expires

cloxy

Super Moderator
Екип
Доста статии чета напоследък за скоростта на сайтовете в Интернет и в много малко от тях се говори за най-важното в тази област - кеширането на ниво браузър. Всички смаляват картинки, компресират с mod_deflate и подобни глупости. Идеята ми е в тази тема с общи усилия да изградим един колкото се може по-оптимален и универсален код за кеширане чрез модула на Apache - mod_expires. До момента съм стигнал до следното:

Код:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 1 hour"
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresDefault "access plus 1 day"
</IfModule>

Ще обновявам този код, ако имам права, спрямо вашите предложения. Логиката ми е проста - HTML типовете се кешират за най-малко време, за да е приложимо и за динамични сайтове. CSS и JavaScript се пазят една седмица, защото може да се наложи да правим някакви промени по тях. Изображенията се пазят месец, като това е малко, но едва ли някой браузър би ги пазил повече поради голямото място, което заемат.

Очаквам някакви предложения за оптимизация. Вие сте на ход!
 
Re: Да направим оптимално кеширане с mod_expires

Аз в последно време наблегнах на кеширането с цел ЦПУ време и имам успех.
За браузъра обаче не съм се замислял. Интересно по дефолт браузъра не кешира ли?
Не съм го смятал за приоритетно, понеже все си мислех, че той си го поддържа и работи.

Във всеки случай може да се окаже по-добро от GZIP като метод, понеже изглежда не харчи ЦПУ, понеже няма общо със сървъра. 🙂
 
Re: Да направим оптимално кеширане с mod_expires

Всичко хубаво, ама това нещо не си го домислил:

HTML типовете се кешират за най-малко време, за да е приложимо и за динамични сайтове

Няма смисъл от това - динамичния контент, ако ще го кешираш, то кеш хеадер-а се подава от самия софтуер зад този контент.

И между другото .php файлове дори и да пускат хеадер "Content-Type: text/html;" няма да ги хванеш с този ред:

ExpiresByType text/html "access plus 1 hour"


Подаването на expire период е също толкова важно, колкото и компресирането от страна на сървъра.
expire периода е _много_ полезен когато имаме едни и също посетители, но ако посещенията ни не са на редовни посетители - то с mod_expires само тъпчем хардовете на хората с излишни файлове 😉
Аз лично бих сетнал expire периода на JS и CSS на повече от година. Това, че файла в някакъв момент ще бъде подменен изобщо не е място за пристенение, просто към адреса на файла добавяте дата на последната му модификация:
<link rel="stylesheet" type="text/css" href="style.css?v=<?=filemtime(style.css);?>" />

Така автоматично кеша отпада при промена на файла🙂

Моята тактика е подаване на E-tag хеадери.
 
Re: Да направим оптимално кеширане с mod_expires

А какво целиш с това кеширане ? Не мислиш ли, че е възможно в един момент това което трябва да се вижда и това което се може да се окажат 2 различни неща ? Според мен не е приложимо в абсолютно всички случаи. Разбира се има и изключения когато би могло да бъде много полезно.
Освен това ако искаш да го ползваш мисля, че можеш да постигнеш ефекта с кеширането и чрез скрипта който ти генерира съдържанието което пък е много по-гъвкаво и тогава мисля, че ще върши точно това което ти трябва.

@BornToDrink в твоя случай също не мисля, че ще ти свърши работа, защото хостинг доставчиците не отброяват сервирането на картинки, js и css файлове, а само изпълнението на php/cgi скриптовете.
 
Последно редактирано:
Re: Да направим оптимално кеширане с mod_expires

Аз ползвам ето това от доста време в .htaccess файловете ми:
Код:
<ifModule mod_expires.c>
  ExpiresActive On
  ExpiresDefault "access plus 1 seconds"
  ExpiresByType text/html "access plus 1 seconds"
  ExpiresByType image/gif "access plus 2592000 seconds"
  ExpiresByType image/jpeg "access plus 2592000 seconds"
  ExpiresByType image/png "access plus 2592000 seconds"
  ExpiresByType text/css "access plus 604800 seconds"
  ExpiresByType text/javascript "access plus 216000 seconds"
  ExpiresByType application/x-javascript "access plus 216000 seconds"
</ifModule>
<ifModule mod_headers.c>
  <filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
    Header set Cache-Control "max-age=2592000, public"
  </filesMatch>
  <filesMatch "\\.(css)$">
    Header set Cache-Control "max-age=604800, public"
  </filesMatch>
  <filesMatch "\\.(js)$">
    Header set Cache-Control "max-age=216000, private"
  </filesMatch>
  <filesMatch "\\.(xml|txt)$">
    Header set Cache-Control "max-age=216000, public, must-revalidate"
  </filesMatch>
  <filesMatch "\\.(html|htm|php)$">
    Header set Cache-Control "max-age=1, private, must-revalidate"
  </filesMatch>
</ifModule>
и сайтовете са значително по-бързи при зареждане от същият браузер.
 
Re: Да направим оптимално кеширане с mod_expires

@BornToDrink в твоя случай също не мисля, че ще ти свърши работа, защото хостинг доставчиците не отброяват сервирането на картинки, js и css файлове, а само изпълнението на php/cgi скриптовете.

Поправи ме ако греша:

Хостинг доставчиците мерят процесорно време на даден потребител, а файловете (били те статични или изпълними) се сервират чрез процес пуснат в suexec. Тоест в процесорното време се отчита и изразходеното такова от сервирането на статично съдържание (картинки, css,js и тн).

Всъщност тук май въпроса стой различно при различните конфигурации на уеб сървъра🙂
 
Re: Да направим оптимално кеширане с mod_expires

Поправи ме ако греша:

Хостинг доставчиците мерят процесорно време на даден потребител, а файловете (били те статични или изпълними) се сервират чрез процес пуснат в suexec. Тоест в процесорното време се отчита и изразходеното такова от сервирането на статично съдържание (картинки, css,js и тн).

Всъщност тук май въпроса стой различно при различните конфигурации на уеб сървъра🙂

Ами на 99% си мисля, че грешиш. За да се определи на кого е даден скрипт доставчика го прекарва през suexec/suphp, но това е само за php/cgi файловете. Останалите не минават през wraper и следователно няма как да се определи чии са. Това е и една от причините да не се мери времето изразходвано от mysql просто това понятие процесорно време е нещо доста неопределено и променливо.
 
Re: Да направим оптимално кеширане с mod_expires

Ами на 99% си мисля, че грешиш.

Добави още една единица. Проверих и се оказа точно така - обработката и сервирането не минават през suexec-а. Съответно не се броят като активност на дадения потребител.

Най-вероятно това е и причината mod_deflate/mod_gzip и тн да не са включени по повечето хостиниги 🙂
 
Re: Да направим оптимално кеширане с mod_expires

Във връзка с това ми се въртят едни мръсни мисли как се заобикаля това процесорно време 🙂 , но не етично и не бих го причинил на никой колега.
 
Re: Да направим оптимално кеширане с mod_expires

Не очаквах, че ще има толкова писано по темата. Идеята ми не е толкова спестяване на процесорно време (това вече го обсъждахме достатъчно и мисля, че се изчерпа). Идеята ми е просто сайтът да се рендира по-бързо на потребителя (front-end).

При мен на динамичен сайт, при който съдържанието се генерира с PHP и естествено типът му е "text/html", mod_expires успешно си го хваща именно с този тип.

Значи за картинките и за CSS/JS приемаме, че трябва да е колкото се може по-голямо времето за каширане. @mlazarov даде много добра идея с подаването на датата като параметър при извършване на някакви промени.

Чудя се как да настроя кеширането по подразбиране и кеширането на динамични страници. Въобще се чудя трябва ли да ги има или не. Май ще е най-добре да е една минута, примерно?

Проблемът е, че всеки хостинг доставчик при настройката на Apache си ги настройва както си иска тези времена и в повечето случаи повече пречат, токолкото помагат.
 
Re: Да направим оптимално кеширане с mod_expires

Ами на 99% си мисля, че грешиш. За да се определи на кого е даден скрипт доставчика го прекарва през suexec/suphp, но това е само за php/cgi файловете. Останалите не минават през wraper и следователно няма как да се определи чии са. Това е и една от причините да не се мери времето изразходвано от mysql просто това понятие процесорно време е нещо доста неопределено и променливо.

Хайде бе 🙂 има версии на MySQL които дават подорбни статистики за всеки потребител, като busy time, cpu time, видове заявки, празни заявки, колко пъти даден потребител се е вързал и т.н. За статичното съдържание наистина все още не се е появил начин да се определи от кой потребител е, но mysql отдавна може да се следи.
 
Re: Да направим оптимално кеширане с mod_expires

Има версии или всеки mysql, защото има и модули на апаш които режат след определено процесорно време.
 
Re: Да направим оптимално кеширане с mod_expires

Има версии или всеки mysql, защото има и модули на апаш които режат след определено процесорно време.
трябва специален mysql и със специални настройки. Събирането на статистики пък от своя страна хаби ресурси, така че не е подходящо за всички ситуации.

Относно кеширането в браузърите - Това е може би най-добрия начин за подобряване скоростта на сайтовете. Дори и динамичните скриптове е добра идея да се кишират в зависимост колко често се ъпдейтват. Ако поствате 1 статия дневно в блога си, защо да не се зададе кеширане от 1 или 2 часа за text/html (особено ако имате проблеми с голямо процесорно натоварване). Ако имате форум, тогава вероятно е по-добре за него да го намалите на 5 минути примерно или пък да изключите кеширането за страниците а да оставите само за css/js/jpeg/gif/png.
 

Back
Горе