Eigentlich ist es ganz einfach. Aber es wird dennoch häufig vergessen. Die Rede ist vom “Expire” HTTP-Header. Er gibt dem Webbrowser zu erkennen, ab wann eine Resource “veraltet” ist. Typischerweise werden diese Header im Webserver konfiguriert (und nicht in der eigentlichen Applikation). Hier ein Beispiel aus einer Apache HTTP Konfiguration, die dafür sorgt, dass alle statische Komponenten nach einem Tag “veralten”.
<LocationMatch "^/static(.*)"> ExpiresActive On ExpiresDefault "access plus 1 day" </LocationMatch>
Allerdings besteht die Gefahr, dass Codeänderungen aufgrund des clientseitigen Caches beim Kunden erst sich nach einem Tag manifestieren. Eine Lösung ist, den Resourcen einen Timestamp des Deployments zu geben, so dass sie quasi endlos gecached werden können. Bei einem neuen Deployment erhalten die Resourcen einen neuen Timestamp. Mehr zu Frontend Best Practises gibts hier.
*Anmerkung am 07.10.2012*:
Anstelle des Expires-Header aus der HTTP/1.0+ Spezifikation, sollte besser der Cache-Control:max-age-Header aus der HTTP/1.1 Spezifikation verwendet werden, weil dieser eine relative Zeitangabe in Sekunden nutzt. Die absoluten Werte des Expires-Header setzen voraus, dass Server und Client die korrekte Uhrzeit verwenden, was nicht immer garantiert werden kann.
*Anmerkung am 08.03.2013*:
Hier noch ein weiteres Praxisbeispiel, in dem explizit Last-Modified/ETag Header abgeschaltet wird. Zugleich werden auch nur statische Resourcen mit dem Header versehen.
Wichtig ist noch der Hinweis, dass das mod_expires.so Modul aktiviert sein muss.
<LocationMatch "/etapp/.*\.(ico|pdf|jpe?g|png|gif|js|css)$">
Header unset Last-Modified
Header unset Date
Header unset ETag
ExpiresActive On
ExpiresDefault "access plus 20 minutes"
</LocationMatch>