• Strona główna
  • Curriculum Vitae
  • O mnie
  • Mapa strony
  • Kontakt
Niebieski Pomarańczowy Zielony Różowy Fioletowy

HTTP Expires w Apache

Opublikowane 13 czerwca 2010. Autor: Kamil Brenk. Wizyt: 1 371.

Kategorie: Apache
Tematyka: Apache, dyrektywa IfModule, mod_expires, optymalizacja serwisów, praktyczne skrypty, Protokół HTTP, wydajność serwisów internetowych

cze 13

Był wpis o ETag (protokół HTTP), teraz czas na alternatywne rozwiązanie buforowania w przeglądarce klienta. Mowa tutaj o nagłówku Expires, który pozwala na jeszcze efektywniejsze usprawnienie buforowania niż wcześniej omawiany nagłówek ETag.

Co robi nagłówek Expires w praktyce? Jak zautomatyzować dołączanie tego nagłówka do wszystkich obiektów pobieranych z serwera Apache? O tym w niniejszej notce.

Nagłówek Expires jest wysyłany przez serwer w nagłówkach HTTP do klienta (HTTP Responses). Wygląda on mniej więcej następująco:

1
Expires: Thu, 01 Dec 1994 16:00:00 GMT

Wartością tego nagłówku jest data ważności dokumentu przesyłanego do klienta (przeglądarki). Przeglądarka odczytuje tę datę – jeżeli data jest późniejsza niż obecna oraz przeglądarka posiada dany plik w buforze – odczytuje ten plik bezpośrednio z buforu (o ile taki posiada) i kończy komunikację z serwerem.

Dzięki temu zaoszczędzasz na transferze serwera, a klient otrzymuje obiekt bezpośrednio z buforu, co znacząco skróca czas wczytywania strony.

Expires vs ETag

Nagłówek ten jest o tyle lepszy od nagłówka ETag, iż nie wymaga sprawdzania aktualności plików w buforze i na serwerze, co zabierało sporo czasu.

Z drugiej strony jest to też wada, gdyż nie ma pewności, iż obiekt który otrzyma klient jest nadal aktualny.

Sam musisz ocenić dla których plików dać jaki nagłówek. Jedno jest pewne – jeżeli nie zamierzasz w najbliższych miesiącach zmienić danego obiektu (pliku graficznego, animacji) i dopuszczasz przechowywanie przez klienta tego pliku w buforze – nagłówek Expires będzie lepszym rozwiązaniem.

Musisz także wiedzieć, że wysyłając do klienta w odpowiedzi HTTP zarówno nagłówek ETag, jak i Expires – nagłówek ETag będzie miał pierwszeństwo i tym faktem będzie się kierowała przeglądarka.

Expires i Apache

Serwer Apache udostępnia specjalny moduł, który w sposób ekspresowy pozwala zająć się nagłówkiem Expires. Mowa oczywiście o mod_expires.

Stosowane przeze mnie ustawienia dla tego modułu wyglądają następująco (.htaccess):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<IfModule mod_expires.c>
    Header set cache-control: public
    ExpiresActive on
    ExpiresDefault "access plus 1 month"
    ExpiresByType text/html             "access plus 1 hour"
    ExpiresByType application/rss+xml   "access plus 1 hour"
    ExpiresByType image/png             "access plus 1 month"
    ExpiresByType image/jpg             "access plus 1 month"
    ExpiresByType image/jpeg            "access plus 1 month"
    ExpiresByType video/ogg             "access plus 1 month"
    ExpiresByType audio/ogg             "access plus 1 month"
    ExpiresByType video/mp4             "access plus 1 month"
    ExpiresByType image/x-icon          "access plus 1 year"
    ExpiresByType font/ttf              "access plus 1 year"
    ExpiresByType image/svg+xml         "access plus 1 year"
</IfModule>

Co tutaj się wyprawia? Najpierw użyta została wcześniej wspomniana dyrektywa IfModule. Sprawdza on, czy na danym serwerze został wbudowany moduł mod_ expires. Jeśli modułu brak, to kod zostaje pominięty.

Następnie wykorzystujemy dyrektywę Header do ustawienia nagłówka HTTP, jakim jest Cache-Control. Ma to na celu zmuszenie przeglądarek do korzystania z buforowania (jeśli mają taką funkcjonalność zaimplementowaną).

Gdyby nagłówek Cache-Control został ustawiony na wartość no-cache to inne nagłówki odpowiedzialne za buforowanie zostałyby zignorowane.

Następnie uruchamiamy moduł przez wpisanie dyrektywy:

1
ExpiresActive on

Kolejnym krokiem jest ustawienie domyślnej „daty ważności” dla wszystkich plików wczytywanych z serwera poprzez dodanie dyrektywy:

1
ExpiresDefault "access plus 1 month"

Powoduje to domyślne ustawienie dla wszystkich plików z serwera nagłówka Expires na bieżącą datę pobrania pliku z serwera + 1 miesiąc.

Kolejne dyrektywy ustawiają datę ważności dla wybranych typów plików (typ MIME). Powoduje to nadpisane domyślnych ustawień dla wybranych rodzajów plików, a robi się to w następujący sposób:

1
2
ExpiresByType text/html                 "access plus 1 hour"
ExpiresByType application/rss+xml       "access plus 1 hour"

Dokumenty HTML i XML (np. sitemap.xml, kanały RSS i Atom) są natomiast przechowywane przez 1 godzinę:

1
2
3
4
5
6
ExpiresByType image/png         "access plus 1 month"
ExpiresByType image/jpg         "access plus 1 month"
ExpiresByType image/jpeg        "access plus 1 month"
ExpiresByType video/ogg         "access plus 1 month"
ExpiresByType audio/ogg         "access plus 1 month"
ExpiresByType video/mp4         "access plus 1 month"

Pliki multimedialne oraz graficzne przechowywane są w buforze przez jeden miesiąc od czasu ostatniego pobrania:

1
2
3
ExpiresByType image/x-icon      "access plus 1 year"
ExpiresByType font/ttf          "access plus 1 year"
ExpiresByType image/svg+xml     "access plus 1 year"

Najdłużej w buforze przeglądarki są przechowywane pliki najrzadziej aktualizowane, czyli ikony (favicon.ico), pliki czcionek oraz grafika w formacie SVG.

Kilka słów podsumowania

I to by było na tyle. Niewiele trudu trzeba włożyć w to rozwiązanie, a może dać całkiem korzystne efekty dla każdej ze stron (klient & serwer).

Z drugiej strony, powyższe rozwiązanie jest niezbyt uniwersalne. Co jeśli serwerem nie będzie Apache? Jak więc widzisz, nie jest to idealne rozwiązanie. Czasem lepiej poświęcić trochę więcej czasu, napisać prostą klasę w PHP i mieć ustawianie nagłówków Expires (buforowania i innych) na poziomie języka, nie serwera.

Decyzja jednak należy do każdego indywidualnie. Będę jednak wdzięczny za podzielenie się sposobem wykorzystywanym przez innych programistów :-).

Podobne wpisy

  • Buforowanie – HTTP ETag
  • Kompresja JavaScript
  • Kompresja CSS
  • Jak pobierać zewnętrzne zasoby?
  • Kompresja w Apache (deflate)

Komentarze (2)

  1. maly 25 grudnia 2010

    To co napisałeś o „no-cache” trochę gryzie się z tym, co mamy tutaj:
    http://pl.wikipedia.org/wiki/Lista_nag%C5%82%C3%B3wk%C3%B3w_HTTP#Cache-Control
    Z tego co napisałeś wnioskuję, że no-cache = no-store, a wiki mówi, że właśnie dla no-cache jest sprawdzana aktualność strony…

  2. Kamil Brenk 26 sierpnia 2011

    maly, przepraszam za tempo odpowiedzi, nie wiem jakim cudem przeoczyłem Twój komentarz.

    Zarówno no-cache, jak i no-store nie mogą pojawić się wraz z Expires z prostego powodu – jeden nie pozwala trzymać plików w buforze, a drugi każdorazowo każe sprawdzać aktualność pliku (czyli robi to samo co ETag i ma te same wady wydajnościowe). Dlatego też ważne jest, by nagłówek Cache-control ustawić na „public” :)



Dodaj komentarz

XHTML: Możesz użyć następujących tagów
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Kamil Brenk Blog

PHP, JavaScript, SQL, HTML

  • Informacje o blogu

    Kamil Brenk

    Blog o tworzeniu aplikacji na potrzeby sieci Web.

    Praktyczne przykłady, porady i sztuczki. PHP, SQL, AJAX, JavaScript, HTML i pochodne.

    Kanał RSS

    • Najnowsze
    • Komentarze
    • Popularne
    • Gramatyka w HTML i CSS
    • PHP kontra Microsoft Office, part I
    • Cross-Domain JavaScript: CORS
    • Wysyłanie wiadomości SMS w PHP
    • Boilerplate 2.0
    • Własne selektory w jQuery
    • Kamil Brenk: @Michał:1) jak już otrzymam dyplom to zrobię serię o...
    • Michal Wachowski: Po pierwsze - tyle czekania i tylko to? A bu! :) Po drugie -...
    • Kamil Brenk: @CapaciousCore: języki kompilowane są szybsze niż...
    • CapaciousCore: @Kamil Brenk wiem, że komentarze i post nie są uber świeże....
    • Kamil Brenk: @CapaciousCore: post i komentarze napisane ponad rok temu;...
    • CapaciousCore: Przebrnąłem przez te wszystkie komentarze i mam trochę...
    • Kamil Brenk: @arhiman: dzięki za komentarz :)A to dziwne co piszesz, bo...
    • Przyszłość PHP
    • Niestandardowe czcionki na stronie
    • Gramatyka w PHP, część 1
    • Umowa i zaliczka dla freelancera
    • Projekt aplikacji po stronie klienta
    • Własny mechanizm Feed
    • jQuery.extends dla PHP
  • Szukajka
    Wpisz co chcesz wyszukać na stronie…
  • Kategorie
    • Apache
    • Freelancer
    • Front-end Development
    • HTML5 & CSS3
    • Inne
    • JavaScript
    • Książki
    • PHP
    • Po godzinach
    • Pozycjonowanie
    • Protokół HTTP
    • SQL
    • Wyrażenia regularne
  • Moje serwisy
    • Testy zawodowe
    • Miłość, uczucia i seks
  • Czytane blogi
    • Wojciech Sznapka
    • Wojciech Soczyński
    • Michał Wachowski
    • Tomasz Kowalczyk
    • JavaScript po polsku | Code42
  • Archiwum
    • Luty 2012
    • Listopad 2011
    • Październik 2011
    • Wrzesień 2011
    • Sierpień 2011
    • Lipiec 2011
    • Maj 2011
    • Kwiecień 2011
    • Marzec 2011
    • Luty 2011
    • Styczeń 2011
    • Grudzień 2010
    • Listopad 2010
    • Październik 2010
    • Wrzesień 2010
    • Sierpień 2010
    • Lipiec 2010
    • Czerwiec 2010
    • Maj 2010
    • Kwiecień 2010
    • Marzec 2010
    • Luty 2010
    • Styczeń 2010
  • Strona główna
  • Curriculum Vitae
  • O mnie
  • Mapa strony
  • Kontakt

Kamil Brenk © 2010. All rights reserved.

Designed by FTL Wordpress Themes brought to you by Smashing Magazine.

Do góry ∧