I set up a subdomain on my site purely to improve site speed (to spread HTTP requests over multiple, cookieless domains, as recommended by Google). I've been experimenting and it looks like my .htaccess caching settings aren't having the same effect on the subdomain.
Compare these two URLs and their response/caching times:
http://www.scenepointblank.com/assets/img/features/coming_in_2012_homepage.png (original)
http://img.scenepointblank.com/features/coming_in_2012_homepage.png (subdomain)
Looking at the response headers it seems to have picked up the same cache_control, but the actual response times vary quite massively (I see an average of ~400ms for www and ~4s for img).
My .htaccess file is at the root of the domain and to experiment I also put a duplicate in scenepointblank.com/assets/img/ to no effect. The contents of the file are below:
FileETag MTime Size
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch .php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior.
ExpiresActive Off
</FilesMatch>
</IfModule>
# 480 weeks
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=290304000, public"
</FilesMatch>
Any ideas why this could be happening?
Seem to have fixed this by adding the following to .htaccess:
ExpiresActive On
ExpiresByType image/png "now plus 365 days"
ExpiresByType image/jpeg "now plus 365 days"
ExpiresByType image/gif "now plus 365 days"
ExpiresByType text/css "now plus 365 days"
Related
Somehow I need to confirm how htaccess expires headers works when used in the home directory as well as subdirectories.
Let's say I have this in the home directory's htaccess:
ExpiresActive On
ExpiresByType image/gif "access plus 1 month"
Then let's say I have this in an htaccess in a /thumbnails/ subdirectory:
ExpiresActive On
ExpiresByType image/gif "access plus 1 year"
So globally on the site, GIF images are meant to cache for a month, but for the /thumbnails/ directory, GIF images are meant to cache for a year. Am I correct in assuming that the htaccess in the /thumbnails/ directory will override the htaccess in the home directory? Or is it vice versa? Any documentation confirming as such?
Your assumption is correct. The Apache's documentation for any directive consists of a section called Context.
The precedence follow the rules base on AllowOverride directive. If your server is configured to allow overriding for the Expires module, then the configuration from /thumbnails/ will take precedence.
This is my code to specify cache expirations:
# Expires
ExpiresActive On
ExpiresDefault "access plus 1 year"
Header unset Last-Modified
Header set Cache-Control "public"
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi|html?)$">
Header set Cache-Control "private, must-revalidate, proxy-revalidate"
ExpiresDefault A0
ExpiresActive Off
</FilesMatch>
-I'm running APACHE on mediatemple. - Do I have to include an .htaccess file with this code on every directory or is there a way to make it work for the whole site?
I used Chrome to audit my site and I discovered .js and .css files weren't being cached though I had set up my .htaccess file to do so.
I removed everything from my site's root htaccess file except the code below and I'm still getting the message "The following resources are explicitly non-cacheable. Consider making them cacheable if possible" in Chrome indicating my main external .js and .css files aren't being cached. These files and images represent like 90% of the total download size so not being able to cache them is driving me crazy.
This is currently the code of my .htaccess file. Having it exactly like this still doens't cache anything.
# Disable Etags
Header unset ETag
FileETag None
# Expires
ExpiresActive On
ExpiresDefault "access plus 1 year"
Header unset Last-Modified
Header set Cache-Control "public"
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi|html?)$">
Header set Cache-Control "private, must-revalidate, proxy-revalidate"
ExpiresDefault A0
ExpiresActive Off
</FilesMatch>
# Enable Compresion
<FilesMatch ".(js|css|html|htm|php|xml)$">
SetOutputFilter DEFLATE
</FilesMatch>
You can see this code not working at http://lujanventas.com
How can I set cache control public to .css, .js and image files?
I'm not an expert with cache controls and expire headers, but I always use this code and it always works (I'm not quite sure if that's what you are looking for but I post it anyway, see if it works for you or not) :
#################
# CACHE HEADERS #
#################
## BEGIN Expire headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 7200 seconds"
ExpiresDefault "access plus 1 seconds"
ExpiresByType image/jpg "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
AddType image/x-icon .ico
ExpiresByType image/ico "access plus 2592000 seconds"
ExpiresByType image/icon "access plus 2592000 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType text/css "access plus 2592000 seconds"
ExpiresByType text/javascript "access plus 2592000 seconds"
ExpiresByType text/html "access plus 7200 seconds"
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType application/xhtml+xml "access plus 7200 seconds"
ExpiresByType application/xhtml+xml "access plus 1 seconds"
ExpiresByType application/javascript "access plus 2592000 seconds"
ExpiresByType application/x-javascript "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
</IfModule>
## END Expire headers
#################
# CACHE CONTROL #
#################
## BEGIN Cache-Control Headers
<IfModule mod_headers.c>
<FilesMatch "\\.(ico|jpe?g|png|gif|swf|gz|ttf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(css)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\\.(js)$">
Header set Cache-Control "max-age=2592000, private"
</FilesMatch>
<filesMatch "\\.(html|htm)$">
Header set Cache-Control "max-age=7200, public"
Header set Cache-Control "max-age=1, public"
</filesMatch>
# Disable caching for scripts and other dynamic files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>
</IfModule>
## END Cache-Control Headers
########
# ETAG #
########
## KILL THEM ETAGS
Header unset ETag
FileETag none
At the moment of writing, your running server generates headers that way for JavaScript:
Expires: access plus 1 day
This is incorrect, it should have been replaced by effective date and time. So it explains no browser is able to cache the resource properly.
According to documentation, there is no reason why it does not work.
Is there any hidden character in your configuration that prevents Apache2 to parse the line properly ? Try to delete the line ExpiresDefault line and type it again from scratch in an reliable text editor.
If still failing, where does your Apache2 version/binary comes from ?
ExpiresActive On
ExpiresDefault A0
# 1 Week expire
<filesMatch "\.(gif|jpg|jpeg|png|swf|css|js)$">
ExpiresDefault A604800
Header append Cache-Control "public"
</filesMatch>
#No caching
<filesMatch "\.(pl|php|cgi|spl|scgi|fcgi|html)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
I believe this should work.
In your config file modify:
Header set Cache-Control "public"
to look like
Header set Cache-Control "public max-age=31536000"
So your files get cached for at least a year (max-age is in seconds).
Why? I loaded your page twice and i saw the request sends a max-age=0
Also, check out this page, it gives some insights in the mod_expires module.
I inputted the following into my ".htacces" file in order to start caching the Web Content. According to Google Page Speed and Yslow the pages are still not Cached. Are the modules wrong? Or is it that the apps are not showing the data correctly?
Site is running on Apache 2.0 on Server
.htaccess (part with caching modules):
# Expire headers
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</ifModule>
# Cache-Control Headers
<ifModule mod_headers.c>
#month
<filesMatch "\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
#week
<filesMatch "\.(css|js)$">
Header set Cache-Control "max-age=604800, public"
</filesMatch>
#day
<filesMatch "\.(x?html?|php)$">
Header set Cache-Control "max-age=43200, private, must-revalidate"
</filesMatch>
</ifModule>
# END Cache-Control Headers
# Turn ETags Off
<ifModule mod_headers.c>
Header unset ETag
</ifModule>
FileETag None
# Remove Last-Modified Header
<ifModule mod_headers.c>
Header unset Last-Modified
</ifModule>
Go into httpd.conf and look for the mod_expires line, it should not be commented out. Look for the mod_headers line and make sure it is not commented out.
Or (not for a critical app) there is an easy and dirty test: remove <ifModule mod_expires.c> and </ifModule> leave stuff in between, same goes for <ifModule mod_headers.c> and if your server fails with 500 internet Server Error then your probably missing one or both of those modules and they are not enabled. If so then go into httpd.conf and enable what you need.
You can also test your site's response headers using a tool like REDbot. Simply pick a resource URL like one pointing to an image and paste it in the tool to see what headers get sent back along with some recommendations. Note that it follows the domain's robots.txt rules and will not check the resource if it is disallowed.
And like Gerben said, using the net tab in firefox, chrome dev tools, or some equivalent web developer tool helps see what headers are being sent and received.
You also don't need to set Cache-Control public. And you don't need to use max age if you're also using ExpiresByType calls.
For more info read this great tutorial: http://www.mnot.net/cache_docs/
And learn by example: checkout how it is done in the html5-boilerplate at https://github.com/h5bp/html5-boilerplate/blob/master/dist/.htaccess
For other popular server config examples like lighthttpd, Node.js, Nginx, etc. see:
https://github.com/h5bp/server-configs
I'm in a pickle here. I tried to set up caching using htaccess files. I made the mistake of setting the htaccess to maintain a cache of html and text files as well. The result was that since the site is a dynamic web application the html would be always generated based upon whatever activity is taking place on the site. However it keeps showing old cache.
I removed all entries from the htaccess file concerning the caching and even deleted my local cache. However its not working. What do I do here.
What happened was that I had put in the following code in the htaccess file:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 30 days"
ExpiresByType image/gif "access plus 60 days"
ExpiresByType image/jpg "access plus 60 days"
ExpiresByType image/png "access plus 60 days"
ExpiresByType application/x-javascript "access plus 60 days"
ExpiresByType text/css "access plus 60 days"
ExpiresByType image/x-icon "access plus 360 days"
</IfModule>
The first line in the snippt was the blunder here. Because of this I could only access old cached pages even though information on the site changes drastically. I removed the entire line however it hasn't worked at all as even now after having cleared my browsers cache hundreds of times I am still seeing cached results.