Search code examples
google-chromemicrosoft-edgecache-controletagmax-age

Caching in HTTP requests: ETag vs max-age


I have a SPA which consumes some static assets from the backend server. For reasons, I picked ETag validation as the caching mechanism. In short, I want the browser keep the assets in its cache forever, as long as the related ETags remain unchanged.

To signal the browser about caching, header Cache-Control must be present in the the responses. To me it's absolutely comprehensible, but what makes me confused is that I have to provide max-age in the header as well. In other words Cache-Control=public doesn't work whereas Cache-Control=public, max-age=100 is the correct header.

To me it sounds contradictory. The browser inquiries the server to see if an asset has changed using If-Not-Match={ETag} any time it asks for it. What's the role of max-age here then?


Solution

  • The resource/file cached in browser with ETag will be anyway requested each time. If this is a *.js file that was changed on server then server will send a new version with a new ETag and browser will refresh it's cached version. But anyway performed a full network round trip of request and response and this is quite expensive. If you do expect that some file really may change at any time then you have to use ETag.

    The Cache-Control is a directive to a browser to not even try to retrieve an updated version for some time specified by the max-age. This is much more performant. This is useful for static assets that probably wont be changed e.g. jquery-3.1.js file will be always the same. Or even if the resource was changed it's not a big deal e.g. style.css.

    During development when assets often changed the Cache-Control is usually disabled.

    But please be careful with the public modifier: that means that the resource may be cached on a proxy server (like CloudFlare) and shared between different users. If the resource have private info e.g. messages then users may see data of each others.