Nagłówki ETag i Expires, czyli cachowanie elementów strony w przeglądarce
|W czasie odwiedzin strony, poszczególne jej elementy są zapisywane w pamięci podręcznej przeglądarki, z której w razie potrzeby mogą być odczytywane. Aby to dobrze wykorzystać ustawiamy odpowiedni czas ważności elementów. Do tego celu służą nagłówki ETag i Expires.
https ETag
Nagłówek ETag informuje czy plik został zmieniony i czy jest konieczność ponownego pobrania z serwera. Analizowany jest w pierwszej kolejności, a gdy jest włączony pomijane są inne nagłówki. Porównywanie opiera się na zmianie rozmiaru, dacie ostatniej modyfikacji lub sumy kontrolnej. Wymagane jest wysłanie zapytania do serwera o wystąpienie zmian. Dodatkowo nie zawsze działa to jak należy np. jeżeli po edycji obrazka jego rozmiar się nie zmienił, nowy obrazek nie będzie pobrany.
Całkowite wyłączenie nagłówka dla wszystkich elementów >>> nagłówek będzie całkowicie pomijany. Ale w tej sytuacji powinniśmy ustalić czas ważności dla plików html/xml za pomocą nagłówka Expires.
Header unset ETag
FileETag None
Wyłączenie dla wybranych plików:
<FilesMatch ".(gif|jpe?g|png)$">
FileETag None
</FilesMatch>
https Expires
Nagłówek Expires, informuje jak długo dany obiekt jest aktualny. Sposób pozwala wykorzystać pamięć podręczną przeglądarki do szybszego ładowania wybranych elementów. Przeglądarka odczytuje datę ważności i jeżeli plik się nie przedawnił, pobierany jest z cache przeglądarki. Ogranicza to ilość żądań do serwera, ograniczamy zużycie transferu, a strona ładuje się szybciej. Sami określamy dla których plików ustawimy nagłówek wygaśnięcia. Nagłówek przydatny do cachowania statycznych, rzadko modyfikowanych plików jak obrazki, ikony, style css itp.
Aby przeglądarka brała pod uwagę ten nagłówek konieczne jest wyłączenie nagłówka ETag dla plików, które chcemy w ten sposób buforować. Dopiero w momencie wyłączenia ETag przeglądarka będzie opierać się na Cache-Control oraz Expires header.
Nagłówek używamy dodając kod do .htaccess. Przykładowo poniższy kod ustawia czas ważności dla plików obrazków i css na 30 dni (liczba AX…X oznacza sekundy; 2592000 sekund = 30 dni):
ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType text/css A2592000
Chcąc użyć nagłówka dla innych typów plików korzystamy z poniższej ściągawki:
application/x-javascript; text/html; text/richtext; image/svg+xml; text/plain; text/xsd; text/xsl; text/xml; video/asf; video/avi; image/bmp; application/java; video/divx; application/msword; application/x-msdownload; image/gif; application/x-gzip; x-icon; image/jpeg; application/vnd.ms-access; audio/midi; video/quicktime; audio/mpeg; video/mp4; video/mpeg; audio/ogg; application/pdf; image/png; audio/x-realaudio; application/x-shockwave-flash; application/x-tar; audio/wma; application/zip
Bardziej zaawansowany kod:
ExpiresActive On
ExpiresByType text/html A1
ExpiresByType application/xhtml+xml A1
# Add Expire header set to 30 days (far future)
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000
ExpiresByType application/javascript A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType image/vnd.microsoft.icon A2592000
ExpiresByType image/svg+xml A2592000
ExpiresByType text/plain A2592000
# Add Expire header set to 1 day
ExpiresByType text/xml A108000
ExpiresByType application/x-httpsd-php A108000
ExpiresByType application/x-httpsd-fastphp A108000
ExpiresByType application/x-httpsd-php-source A108000
# Add Expire header set to 1 hour
ExpiresByType application/xml A108000
ExpiresByType application/atom+xml A108000
ExpiresByType application/rss+xml A108000
Przykład 1
Kod do zastosowania na większości stron. Dla wybranych typów plików (obrazki, style css, js) ustawiony jest czas ważności na 30 dni (ExpiresDefault A2592000) oraz wyłączony jest ETag. Cache-Control zmusza przeglądarkę do buforowania (ustawienie wartości na „no-cache” powoduje, że inne nagłówki odpowiedzialne za buforowanie zostałyby zignorowane.
<FilesMatch ".(ico|jpg|jpeg|png|gif|js|css|swf)$">
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault A2592000
Header append Cache-Control "public"
</IfModule>
Header unset ETag
FileETag None
</FilesMatch>
Przykład 2
Prosty kod ustawiający nagłówek Expires dla wybranych typów plików.
ExpiresActive On
<FilesMatch ".(jpg|jpeg|png|gif|swf)$">
ExpiresDefault A604800
</FilesMatch>
Przykład 3
Rozbudowany kod. Opis w komentarzach.
# Aktywacja Expires u ustawienie domyslnego czasu na 0
ExpiresActive On
ExpiresDefault A0
# Ustawienie czasu wygasniecia dla plikow medialnych na 1 rok i zmuszenie przegladarki do ich buforowania
<FilesMatch ".(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A29030400
Header append Cache-Control "public"
</FilesMatch>
# Ustawienie czasu wygasniecia plikow graficznych na 1 tydzien i zmuszenie przegladarki do ich buforowania
<FilesMatch ".(gif|jpg|jpeg|png|swf)$">
ExpiresDefault A604800
Header append Cache-Control "public"
</FilesMatch>
# Ustawienie czasu wygasniecia plikow na 2 godziny
<FilesMatch ".(xml|txt|html|js|css)$">
ExpiresDefault A7200
Header append Cache-Control "proxy-revalidate"
</FilesMatch>
# Wymuszony zakaz buforowania dla dynamicznych plikow
<FilesMatch ".(php|cgi|pl|htm)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
Przykład 4
# Expire handler
<IfModule mod_expires.c>
# Aktywacja expirations.
ExpiresActive On
# Cachowanie wszystkich plikow przez tydzien
ExpiresDefault A604800
# Cachowanie przez 1 rok
<FilesMatch ".(ico|pdf|flv)$">
ExpiresDefault A31449600
</FilesMatch>
# Cachowanie przez 1 miesiac
<FilesMatch ".(jpg|png|gif|swf)$">
ExpiresDefault A2592000
</FilesMatch>
# Cachowanie przez 1 miesiac
<FilesMatch ".(xml|txt|css|js)$">
ExpiresDefault A604800
</FilesMatch>
# Cachowanie przez 1 sekunde
<FilesMatch ".(html|htm|php)$">
ExpiresDefault A1
</FilesMatch>
</IfModule>
Przykład 5
# Turn on Expires and set default expires to 3 month
ExpiresActive On
ExpiresDefault A7257600
ExpiresByType image/x-icon A14515200
# Set up caching on media files for 1 month
<FilesMatch “.(gif|jpg|JPG|jpeg|png|PNG)$”>
ExpiresDefault A2419200
</FilesMatch>
# Set up caching on commonly updated files 1 month
<FilesMatch “.(xml|txt|html|js|css)$”>
ExpiresDefault A2419200
</FilesMatch>
<FilesMatch “.(ico|gif|jpg|JPG|jpeg|png|PNG|css|js|html?|xml|txt)$”>
FileETag None
</FilesMatch>
Przykład 6
# Expire images header
ExpiresActive On
ExpiresDefault A0
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/ico A2592000
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000
# kill them etags
FileETag none
Ciekawa strona: Ultimate .htaccess Guide – obszerny przewodnik po .htaccess
Gratuluje, bardzo konkretnie wszystko opisane. Sama metoda prosta lecz bardzo skuteczna, pod kątem optymalizacji sporo możemy zyskać.
Nareszcie jasny i klarowny „dla nieprogramisty” i domowego Webmastera opis działania Etag i Expires. Przykłady zastosowałem w swoich serwisach, bo walczę z przeciążeniem serwera hostingowego.
Rewelacyjnie wytłumaczone podstawy keszowania 🙂 Warto by jeszcze wspomnieć nieco szerzej o dyrektywach (nie jestem pewien czy to poprawna nazwa) stosowanych razem z Cache-Control. Na przykład public sprawia, że zarówno przeglądarka jak i serwery proxy po drodze zawartość strony mogą skeszować (strona może być buforowana). Natomiast private sprawia, że strona jest keszowana tylko po stronie przeglądarki (proxy ma zakaz buforowania). Dyrektywa must-revalidate powoduje, że przeglądarka przed wyświetleniem strony sprawdzi najpierw zgodność zapamiętanego kontentu z tym serwowanym przez serwer i jeśli występują różnice pobierze go ponownie. Jest jeszcze podobne proxy-revalidate które tego samego wymaga od serwerów proxy. Dla bardziej dynamicznych elementów witryny przydatne mogą być dyrektywy no-cache i no-store, co z resztą zostało pokazane w artykule. W przypadku mojego bloga czas przeładowania strony zmalał 10x, a wystarczyło wymusić cache jedynie plików multimedialnych. Gra warta świeczki.
Tak, są to dyrektywy i dzięki, że to szerzej opisałeś.
Dodam od siebie, że dyrektywa no-store zabrania przeglądarce buforowania strony, ale także nawet zapisać stronę w swoim katalogu pamięci podręcznej. Jest najbardziej bezpieczna, używana dla poufnych stron. Natomiast no-cache oznacza (w teorii), że przeglądarka przechowuje strony w pamięci podręcznej, ale wyświetla je dopiero po revalidacji z serwerem. Jeśli strona przechowywana w cache przeglądarki się nie zmieniła, serwer wysyła informację, że strona może być wyświetlona z buforu. Jednak w praktyce może to tak nie działać, przeglądarka może nawet nie buforować strony, dyrektywa może działać jak no-store. Podczas udostępniania poufnych stron polecane jest użycie obu dyrektyw jednocześnie.
Natomiast dyrektywa no-transform informuje o optymalizacji strony dla urządzeń mobilnych, która nie musi być transkodowana.
A można ustawić tak, by dodatkowo tylko z jednego, konkretnego folderu obrazki w ogóle nie będą mogły być przechowywane w pamięci podręcznej, tylko zawsze ładowane z serwera?
Dzięki za fachowe przykłady! Strona która podałeś także dużo wyjaśnia! Najlepszego.
witam, u mnie to nei działa… nie mam pojęcia dlaczego ;/
zastosowałem przykład np. 1 w pliku httcass i nic ;/ pierwszy raz próbuje to robić także nie mam pojęcia co jest nie tak…
proszę o pomoc…
moje gg 8668008
Ja kombinowałem wczoraj chyba dwie godziny i nie chciało ruszyć. Wstawiałem wszystkie możliwo kombinacje jakie znalazłem. Pod koniec wyszło na to że serwer ma zmodyfikowany Apache i trochę inaczej trzeba, to znaczy inne komendy mają 😀
Napisałem do HelpDesk wczoraj od razu i dzisiaj dostałem odpowiedź. Podali wszystko co i jak i teraz działa jak powinno 🙂 Tak więc jeśli coś nie chce działać może warto napisać do HelpDesku gdyż czasami zmodyfikują komendy na własne potrzeby a potem klient bez tej wiedzy nie ma szans sam tego zrobić. Teraz wszystkie pliki jpg, png z drogerii FROCUS są cachowane 🙂
Piszesz „Expires, informuje jak długo dany obiekt jest aktualny. Przeglądarka odczytuje datę ważności i jeżeli plik się nie przedawnił, pobierany jest z cache przeglądarki.”
Rozumuję, że jak się przedawnił pobierany jest z serwera. Innymi słowy korzyści z użycia ETag diabli biorą. Bo gdzie działa Expires nie działa ETag i odwrotnie.
Ponadto mam pytanie co się dzieje z plikami które zachowują termin ważności ? Zapychają cache przeglądarki czy są usuwane ?
Leszek, ETag jest brany pod uwagę w pierwszej kolejności, ma priorytet przed Expires. Tam gdzie działa ETag nie działa Expires, odwrotnie to już nie. Pliki zapisywane są w pamięci podręcznej przeglądarki, są w niej przechowywane. Po upływie terminu ważności są pobierane nowe wersje plików, stare zaś są nadpisywane lub pozostają w cache aż do jej opróżnienia lub są usuwane jeżeli określimy limit rozmiaru pamięci podręcznej.
A co w przypadku plików zewnętrznych jak ustawić ich czas ważności w przeglądarce..
Posiadam widget z opineo i w PageSpeed zaleca aby wykorzystać pamięć przeglądarki dla plików z widgetu jpg i png
Dobra robota! Merytorycznie napisane i bardzo czytelne. Bardzo dobrze się czyta. Gdyby tak wszyscy pisali…
Dzięki! Google Adwords kazały mi poprawić stronę i byłam święcie przekonana, że nie będę potrafiła… aż trafiłam tutaj i teraz wszystko działa !!! 😀
na szczęście ciągle aktualne
Hej mógł byś poradzić coś na to…
https://www.google-analytics.com/analytics.js (2 hours)
https://fonts.goo
gleapis.com/css?family=Open+Sans+Condensed:300,700
https://fonts.googleapis.com/css?family=Raleway:300,400,600
https://fonts.googleapis.com/css?family=Roboto:100,200,300,400,500,600,700|Roboto+Condensed:300,400,700
był bym bardzo wdzięczny 🙂
Witam, da się jakoś ustawić dłuższy czas przechowywania plików bez hataccess? Dokładnie chodzi mi o blogspota, bo tam niestety niewiele da się zrobić, żeby przyspieszyć stronę
Aby zarządzać ustawieniami tego typu trzeba mieć dostęp do serwera, na blogspot to wykluczone.