Nginx aggressive asset configuration
Description
This is still a work in progress. For example I don't like all this blocks with some configuration duplicated. I think it would be better to set common options in one block like below, and then adding other blocks for custom options :
location ~* \.(?:css|js|ico|woff|eot|svg|ttf|otf|png|gif|jpe?g) {
access_log off;
add_header Cache-Control public;
}
location ~* \.(?:css|js|woff|eot|svg|ttf|otf|png|gif|jpe?g) {
expires max;
}
# missing vary header on zippable fonts
location ~* \.(?:eot|ttf|svg)$ {
add_header Vary Accept-Encoding;
}
But in the same time I tend to think that parsing multiple regexps to find the complete configuration for an asset might be not great for performances for nginx. And for an user it can be difficult and error prone to update the configuration. A better idea ?
Configuration
Thus below is the configuration I'm currently testing.
nginx.conf
# Gzip configuration
gzip on;
gzip_static on;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_vary on;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
# don't gzip images, woff
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js font/ttf font/opentype application/vnd.ms-fontobject image/svg+xml;
mime.types
# Add these mime.types
font/ttf ttf;
font/opentype otf;
application/font-woff woff;
application/vnd.ms-fontobject eot;
# Remove this mime.types
application/octet-stream eot;
site configuration
set $rootUrl "/var/www/front/"
location ~* \.(?:ico)$ {
root $rootUrl;
expires 30d;
add_header Cache-Control public;
access_log off;
}
# css and js are tokenized
location ~* \.(?:css|js) {
root $rootUrl;
expires max;
add_header Cache-Control public;
access_log off;
}
# nginx gzip_static does not add Vary header for fonts.
location ~* \.(?:eot|ttf|svg)$ {
root $rootUrl;
expires max;
add_header Vary Accept-Encoding;
add_header Cache-Control public;
access_log off;
}
# woff fonts should not be zipped.
location ~* \.(?:woff)$ {
root $rootUrl;
expires max;
add_header Cache-Control public;
access_log off;
}
# tokenized images can be cached forever
location ~* "\.([a-z0-9]{8})\.(?:gif|png|jpe?g)$" {
root $rootUrl;
expires max;
add_header Cache-Control public;
access_log off;
}
# non tokenized images only cache for 1 week as they are in my context subject to change.
location ~* \.(?:gif|png|jpe?g)$ {
root $rootUrl;
expires 1w;
add_header Cache-Control public;
access_log off;
}
I have one remark about using expires max. Expires date is set to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years. I've read multiple times that an Expires date of more than one year can be result in no caching. Thus I will probably change expires max to expires 1y.
Do you have comments ?
Written by Stéphane Bachelier
Related protips
3 Responses
You could combine those duplicate lines in a block as such:
location ~* .(?(:ico|css|js|woff))$ {
addheader Cache-Control public;
accesslog off;
}
You're right for merging css, js and woff but not for .ico as I only cache the favicon for 30 days.
Changing an favicon.ico is probably never changed but when a client ask for it's better to not wait too long :P
It's still possible to change the favicon path or add a token, to set a longer expires date.
For the Icon you can cache it to the max and when the client ask for a change you just add a fav.ico?v=1.1 and increment the version number if needed.