I want my site to benefit from being cached but the site is updated pretty often. How can I make sure the user is getting the most recent version?
Currently my .htaccess
file looks like this:
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
You can use base as "modification" for the app resources which you anticipate to change often and give access time based on your anticipation. Below is how "modification" works:
Suppose you are anticipating your CSS files to be modified every day then you can use
ExpiresByType text/css "modification plus 1 day"
then this is what will happen (considering you uploaded CSS files on25-09-2015, 23:55
):A client access your page on
25-09-2015, 23:56
and downloads all the CSS files. Now, since Apache sends last modified time in response header so client will certainly getLast-Modified:Fri, 25 Sep 2015 23:55:00 GMT
and since you are usingExpiresByType
directive with "modification" base, so Apache will calculate its expiration time as --> [last modified time (time when resource was last modified in server, in this case it will be 25 Sep 2015 23:55) + time specified with "modification" base (in this case, 1 day)], so the expiration date will be calculated as26 Sep 2015 23:55
and hence Apache will sendExpires: Sat, 26 Sep 2015 23:55:00 GMT
. So, the 2 cache related response headers Apache will send to client will be:Now, lets say client again visits the page on
26 Sep 2015 03:55
then it will see that document is not expired and hence will use cache version of the document. This will go as per your anticipation.26 Sep 2015 23:56
then it will see that document has expired and hence will send a request to server for new document.So, now client will send a request to server everytime it finds that document has expired. When you do a fresh upload then Apache will recalculate the expiration time and will send the same in
Expires
response header.You can have a look at answer of this question, it is very good.
For the resources which you do not anticipate to be modified often, you can continue using "access" as base, like you are already correctly doing for Favicon which cannot be anticipated to change in a year.
Unfortunately Apache cannot fully solve this purpose - "Get fresh document from server only if modified version is available on server else continue using cached document" because until a request is sent to server, client cannot truly know whether document has changed or not. Or PUSH technology needs to be implemented where server pushes some information and client acts based on it.
Some other info:
HTML5 has provided a feature called app-cache/offline-cache which enables offline navigation but it is regarded as broken and will be dis-continued. You can look Service worker if you want to looking to implement user offline experience.