Forum Topic: Cache-Control questions

Forum: .htaccess Forum : WordPress • Posted by Louis Myller • Updated:

I have a WordPress website, although that is relevant only to my last question.

First of, it is well-known that:

“It is important to specify one of Expires or Cache-Control max-age, and one of Last-Modified or ETag, for all cacheable resources. It is redundant to specify both Expires and Cache-Control: max-age, or to specify both Last-Modified and ETag.”

I’m going with the Cache-Control max-age for caching and Last-Modified for validation.

I am using the following code for cache-control in my .htaccess (I copied it from your book and modified it a bit):

<IfModule mod_headers.c>
	FileETag None
	Header unset ETag
	Header unset Pragma
	Header unset Cache-Control
	#Header unset Last-Modified
	
	# default cache 1 year = 31556926 s
	Header set Cache-Control "max-age=31556926, public, no-transform, must-revalidate"
	
	<IfModule mod_alias.c>
		<FilesMatch "\.(html?|json|rss|txt|xhtml|xml)$">
			# cache markup for 1 second
			Header set Cache-Control "max-age=1, public, no-transform, must-revalidate"
		</FilesMatch>
		
		<FilesMatch "\.(js|css)$">
			# cache for 1 week = 604800 seconds
			Header set Cache-Control "max-age=604800, public, no-transform, must-revalidate"
		</FilesMatch>
		
		<FilesMatch "\.(gif|jpe?g?|png|ico)$">
			# cache image files for 1 month = 2629744 seconds
			Header set Cache-Control "max-age=2629744, public, no-transform, must-revalidate"
		</FilesMatch>
		
		<FilesMatch "\.(doc|eot|flv|mp4|ogg|pdf|svg|swf|ttf|otf|woff)$">
			# cache fonts and media files for 1 month = 2629744 seconds
			Header set Cache-Control "max-age=2629744, public, no-transform, must-revalidate"
		</FilesMatch>
	</IfModule>
</IfModule>

So I have a few questions.

1) YSlow complains that I’m not using any Expires headers.

Is that any important nowadays or should I ignore it?

If both Expires and Cache-Control: max-age exist, Cache-Control has priority so the max-age directive overrides the maximum age specified by the Expires header.

Also, Cache-Control is http/1.1 standard and Expires is http/1.0. If the client browser does not support http/1.1 Cache-Control will be ignored, but it’s unlikely that there is a browser that doesn’t support it. Expires depends on accuracy of user’s clock, so it’s mostly a bad choice (as most browsers support HTTP/1.1).

So I guess I should stick to Cache-Control and that I should never use Expires, and ignore YSlow’s recommendation.

What do you think? Am I right?

2) I am supposed to use either ETag or Last-Modified so I am ditching ETag and keep the latter for validation. Is that a good thing to do?

In your implementation you’ve ditched both of them, but I’m not sure I understand why.

3) Why do you unset the Cache-Control header (“Header unset Cache-Control”) since you are setting it again a few lines later?

4) I wanted to use a regex for three extensions in the FilesMatch: jpe, jpg and jpeg.

So would jpe?g? be correct? I know what the question mark does, but I’m not sure how a regular expression works with multiple question marks in it.

5) My final question is what I want to sort out the most.

You can see in the aforementioned code that the default max-age is set to 31556926 and for text/html it is set to 1.

However, when I request a page from my WordPress site, for example this one http://mywordpresssite.com/some-page/, then the max age that is sent in the header is 31556926.

Despite that the Content-Type header is text/html.

How can I modify my code in order to send the desired max-age for html which is 1 second?