HTTP Cache-Control • what should you know

HTTP Cache-Control • what should you know


Wojtek Andrzejczak
Wojtek Andrzejczak
HTTP Cache-Control • what should you know

Caching resources of our application or website is very important. We want to deliver content to the user in the shortest possible time. However, when we make too many elements cached, we can face the opposite side effect, we’ll lose partial control of the freshes of our content when we want to.

Proxy servers

Between our web server and user browser, we can find multiple caching proxy servers, like those from our ISP. Those servers to reduce TCP / UDP traffic inside their network, they use caching servers. So the distance between Browser request and server is reduced. It is suitable not only for user experience and faster loading time but also for internet providers.

The cache is good, right?

Unfortunately, not always. If we allow our content to be cached in a very significant way, we can face opposite situations. We’ll have a problem to re-cache / reload our content. Sometimes happens that proxy cache servers do not purchase/reload the cached content when it is required. It can lead to content maintenance problems.

HTTP Cache-Control header: private

Use this option when the content of the response contains content which might change under the same URL under general conditions. It also means that no cache proxy server should be allowed to cache the response.

HTTP Cache-Control header: public

Recommend usage of this option for the low priority content like website fonts, logos, etc. Elements which does not change. The proxy server will try to cache our content.

HTTP Cache-Control header: no-cache

Very important to use for API responses, redirects. We don’t want this content to be cached at any point.

HTTP Cache-Control header: max-age

Time expressed in seconds, which inform us how long response content should be kept in the cache.

However, I want to use a public cache option for my resources

It is also possible to manage. The important thing here is to remember that the URL is the cache key. When it changes, it defines new content. The common practice in the modern frameworks / CMS systems is to generate hash chunk in the file name. This hash represents the checksum of the file content. So for instead of https://example.com/main.js, we could use https://example.com/main.205199ab45963f6a62ec.js where 205199ab45963f6a62ec is our hash chunk.

Another common practice is adding a query string variable with the version or last modification timestamps like https://example.com/main.js?version=1 or https://example.com/main.js?_=123456789. However, this approach might be a little be not complicated because some cache servers treat query string URL’s as to cachable or ignores them.

Nginx cache configuration

Bellow, you can find my example Server instance configuration for React JS application. Application use Webpack so I’ve hash chunks in the names of the assets.

if ($request_uri ~* ".(ico|css|js|gif|jpe?g|png)") {
    expires 365d;

    access_log off;
    add_header Pragma public;
    add_header Cache-Control "public";
    break;
}

CSS/JavaScript

Image assets

if ($request_uri ~* \.(?:jpg|jpeg|gif|png|ico|xml)$) {
    expires 365d;
    access_log off;
    add_header Pragma public;
    add_header Cache-Control "public";
}

Web Fonts

if ($request_uri ~* \.(?:eot|woff|woff2|ttf|svg|otf)$) {
    expires 365d;
    access_log off;
    add_header Pragma public;
    add_header Cache-Control "public";
    add_header Access-Control-Allow-Origin *;
}

Turn off redirect cache

server {
    listen 80;
    server_name example.com next.example.com

    include snippets/letsencrypt-acme-challenge.conf;

    location / {
        # kill cache
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;
        return 301 https://$host$request_uri;
    }
}

Useful links


  • Contact Me
    Contact me if you need advice or if you need help. Would you please choose the most suitable contact channel for you?

Subscribe to receive updates about new articles.

[newsletter_form button_color=”#E74C3C”]
Show Comments (0)

Comments

Related Articles

7 facts about sandbox attribute • HTML5 iFrame
Troubleshooting

7 facts about sandbox attribute • HTML5 iFrame

Learn three facts about the iframe sandbox attribute. What HTML5 IFrame tag is and how you can use the sandbox attribute.

Posted on by Wojtek Andrzejczak
Firebase Security •  avoid client-side issues
Troubleshooting

Firebase Security • avoid client-side issues

When you use Firebase Project you also create Google Cloud Console Project for all platforms. Generated API keys require a security audit to avoid problems.

Posted on by Wojtek Andrzejczak