nginx:cache_static_files_on_nginx
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
nginx:cache_static_files_on_nginx [2016/10/18 13:17] โ peter | nginx:cache_static_files_on_nginx [2019/12/01 10:25] (current) โ removed peter | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Nginx - Cache static files on Nginx ====== | ||
- | Configure nginx to set the **Expires** HTTP header and the **max-age** directive of the **Cache-Control** HTTP header of static files (such as images, CSS and Javascript files) to a date in the future so that these files will be cached by your visitors' | ||
- | |||
- | ===== Configuring nginx ===== | ||
- | |||
- | The **Expires** HTTP header can be set with the help of the [[http:// | ||
- | |||
- | <file bash> | ||
- | location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { | ||
- | | ||
- | } | ||
- | </ | ||
- | |||
- | In the above example, all //.jpg, .jpeg, .png, .gif, .ico, .css//, and //.js// files get an **Expires** header with a date 365 days in the future from the browser access time. Therefore, you should make sure that the //location {}// block really only contain static files that can be cached by browsers. | ||
- | |||
- | Reload nginx after your changes: | ||
- | |||
- | <code bash> | ||
- | / | ||
- | </ | ||
- | |||
- | You can use the following time settings with the **expires** directive: | ||
- | |||
- | * **off** makes that the **Expires** and **Cache-Control** headers will not be modified. | ||
- | * **epoch** sets the **Expires** header to 1 January, 1970 00:00:01 GMT. | ||
- | * **max** sets the **Expires** header to 31 December 2037 23:59:59 GMT, and the **Cache-Control** max-age to 10 years. | ||
- | * A time without an //@// prefix means an expiry time relative to the browser access time. A negative time can be specified, which sets the **Cache-Control** header to **no-cache**. | ||
- | * A time with an //@// prefix specifies an absolute time-of-day expiry, written in either the form Hh or Hh:Mm, where H ranges from 0 to 24, and M ranges from 0 to 59. Example: //expires @15:34;// | ||
- | |||
- | You can use the following time units: | ||
- | |||
- | * ms: milliseconds | ||
- | * s: seconds | ||
- | * m: minutes | ||
- | * h: hours | ||
- | * d: days | ||
- | * w: weeks | ||
- | * M: months (30 days) | ||
- | * y: years (365 days) | ||
- | |||
- | Examples: 1h30m for one hour thirty minutes, 1y6M for one year and six months. | ||
- | |||
- | Also note that if you use a far future //Expires// header you have to change the component' | ||
- | |||
- | Instead of basing the //Expires// header on the access time of the browser (e.g. //expires 10d;//), you can also base it on the modification date of a file (<color red> | ||
- | |||
- | <file bash> | ||
- | expires modified 10d; | ||
- | </ | ||
- | |||
- | |||
- | ===== Configuring Cache-Control and Expires Headers ===== | ||
- | |||
- | There are two caching control response headers: **Cache-Control** and **Expires**. | ||
- | |||
- | If these headers are set, they can tell the browser that the requested file can be kept locally for a certain amount of time (including forever) without requesting it again. | ||
- | |||
- | We can use the header module to set these HTTP headers. | ||
- | |||
- | To add the header module, edit the default Nginx configuration file. | ||
- | |||
- | <code bash> | ||
- | sudo vi / | ||
- | </ | ||
- | |||
- | Find the server configuration block, which looks like this: | ||
- | |||
- | |||
- | <file nginx / | ||
- | . . . | ||
- | # Default server configuration | ||
- | # | ||
- | |||
- | server { | ||
- | listen 80 default_server; | ||
- | listen [::]:80 default_server; | ||
- | |||
- | . . . | ||
- | </ | ||
- | |||
- | Add the following two new sections here: one before the server block, to define how long to cache different file types, and one inside it, to set the caching headers appropriately. | ||
- | |||
- | <file nginx / | ||
- | . . . | ||
- | # Default server configuration | ||
- | # | ||
- | |||
- | # Expires map | ||
- | map $sent_http_content_type $expires { | ||
- | default | ||
- | text/ | ||
- | text/ | ||
- | application/ | ||
- | ~image/ | ||
- | } | ||
- | |||
- | server { | ||
- | listen 80 default_server; | ||
- | listen [::]:80 default_server; | ||
- | |||
- | expires $expires; | ||
- | . . . | ||
- | </ | ||
- | |||
- | The section before the server block is a new map block which defines the mapping between the file type and how long that kind of file should be cached. | ||
- | |||
- | We're using several different settings in this map: | ||
- | |||
- | * The default value is set to **off**, which will not add any caching control headers. | ||
- | |||
- | * For **text/ | ||
- | |||
- | * For **text/ | ||
- | |||
- | * The last setting is for **~image/ | ||
- | |||
- | Inside the server block, the **expires** directive (a part of the headers module) sets the caching control headers. | ||
- | |||
- | Save and close the file to exit. | ||
- | |||
- | To enable the new configuration, | ||
- | |||
- | <code bash> | ||
- | sudo systemctl restart nginx | ||
- | </ | ||
- | |||
- | Next, let's make sure our new configuration works. | ||
- | |||
- | |||
- | ===== Testing ===== | ||
- | |||
- | To test if your configuration works, you can use the Network analysis function of the Developer tools in the Firefox Browser and access a static file through Firefox (e.g. an image). | ||
- | |||
- | |||
- | ==== Creating Test Files ==== | ||
- | |||
- | In this step, we will create several test files in the default Nginx directory. | ||
- | |||
- | To make a decision about what kind of file is served over the network, Nginx does not analyze the file contents; that would be prohibitively slow. Instead, it just looks up the file extension to determine the file's MIME type, which denotes the purpose of the file. | ||
- | |||
- | Because of this behavior, the content of our test files is irrelevant. | ||
- | |||
- | Create a file named **test.html** in the default Nginx directory using truncate. | ||
- | |||
- | <code bash> | ||
- | sudo truncate -s 1k / | ||
- | </ | ||
- | |||
- | Let's create a few more test files in the same manner: one jpg image file, one css stylesheet, and one js JavaScript file. | ||
- | |||
- | <code bash> | ||
- | sudo truncate -s 1k / | ||
- | sudo truncate -s 1k / | ||
- | sudo truncate -s 1k / | ||
- | </ | ||
- | |||
- | The next step is to check how Nginx behaves with respect to sending caching control headers on a fresh installation with the files we have just created. | ||
- | |||
- | |||
- | ==== Checking the Default Behavior ==== | ||
- | |||
- | By default, all files will have the same default caching behavior. | ||
- | |||
- | So, let's check if **test.html** is served with any information regarding how long the browser should cache the response. | ||
- | |||
- | <code bash> | ||
- | curl -I http:// | ||
- | </ | ||
- | |||
- | You should see several HTTP response headers: | ||
- | |||
- | < | ||
- | HTTP/1.1 200 OK | ||
- | Server: nginx/ | ||
- | Date: Sat, 10 Sep 2016 13:12:26 GMT | ||
- | Content-Type: | ||
- | Content-Length: | ||
- | Last-Modified: | ||
- | Connection: keep-alive | ||
- | ETag: " | ||
- | Accept-Ranges: | ||
- | </ | ||
- | |||
- | In the second to last line you can see the **ETag** header, which contains a unique identifier for this particular revision of the requested file. If you execute the previous curl command repeatedly, you will see the exact same ETag value. | ||
- | |||
- | When using a web browser, the ETag value is stored and sent back to the server with the **If-None-Match** request header when the browser wants to request the same file again โ for example, when refreshing the page. | ||
- | |||
- | We can simulate this on the command line with the following command. | ||
- | |||
- | <code bash> | ||
- | curl -I -H ' | ||
- | </ | ||
- | |||
- | The response will now be different: | ||
- | |||
- | < | ||
- | HTTP/1.1 304 Not Modified | ||
- | Server: nginx/ | ||
- | Date: Sat, 10 Sep 2016 13:20:31 GMT | ||
- | Last-Modified: | ||
- | Connection: keep-alive | ||
- | ETag: " | ||
- | </ | ||
- | |||
- | This time, Nginx will respond with **304 Not Modified**. | ||
- | |||
- | This is useful because it reduces network traffic, but it's not quite good enough for achieving good caching performance. | ||
- | |||
- | In the next step, we will use the headers module to append caching control information. | ||
- | |||
- | |||
- | ===== Testing Browser Caching ===== | ||
- | |||
- | Execute the same request as before for the test HTML file. | ||
- | |||
- | <code bash> | ||
- | curl -I http:// | ||
- | </ | ||
- | |||
- | This time the response will be different. | ||
- | |||
- | <code bash> | ||
- | HTTP/1.1 200 OK | ||
- | Server: nginx/ | ||
- | Date: Sat, 10 Sep 2016 13:48:53 GMT | ||
- | Content-Type: | ||
- | Content-Length: | ||
- | Last-Modified: | ||
- | Connection: keep-alive | ||
- | ETag: " | ||
- | Expires: Thu, 01 Jan 1970 00:00:01 GMT | ||
- | Cache-Control: | ||
- | Accept-Ranges: | ||
- | </ | ||
- | |||
- | The **Expires** header shows a date in the past and Cache-Control is set with no-cache, which tells the browser to always ask the server if there is a newer version of the file (using the ETag header, like before). | ||
- | |||
- | You'll see a difference response with the test image file. | ||
- | |||
- | curl -I http:// | ||
- | Nginx response headers | ||
- | HTTP/1.1 200 OK | ||
- | Server: nginx/ | ||
- | Date: Sat, 10 Sep 2016 13:50:41 GMT | ||
- | Content-Type: | ||
- | Content-Length: | ||
- | Last-Modified: | ||
- | Connection: keep-alive | ||
- | ETag: " | ||
- | Expires: Thu, 31 Dec 2037 23:55:55 GMT | ||
- | Cache-Control: | ||
- | Accept-Ranges: | ||
- | In this case, Expires shows the date in the distant future, and Cache-Control contains max-age information, | ||
- | |||
- | The result should be similar for both test.js and test.css, as both JavaScript and stylesheet files are set with caching headers too. | ||
- | |||
- | This means the cache control headers have been configured properly and your website will benefit from the performance gain and less server requests due to browser caching. You should customize the caching settings based on the content for your website, but the defaults in this article are a reasonable place to start. | ||
- | |||
- | Conclusion | ||
- | The headers module can be used to add any arbitrary headers to the response, but properly setting caching control headers is one of its most useful applications. It increases performance for the website users, especially on networks with higher latency, like mobile carrier networks. It can also lead to better results on search engines that factor speed tests into their results. Setting browser caching headers is one of the major recommendations from Google' | ||
- | |||
- | More detailed information about the headers module can be found in Nginx' | ||
- | |||
- | |||
- | ===== References ===== | ||
- | |||
- | http:// |
nginx/cache_static_files_on_nginx.1476796677.txt.gz ยท Last modified: 2020/07/15 09:30 (external edit)