Last Updated: July 25, 2019
·
17.33K
· stephanebachelier

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 ?

3 Responses
Add your response

You could combine those duplicate lines in a block as such:

location ~* .(?(:ico|css|js|woff))$ {
addheader Cache-Control public;
access
log off;
}

over 1 year ago ·

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.

over 1 year ago ·

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.

over 1 year ago ·