Search code examples
asp.net-mvccachinghttp-headerschirpy

Why/how do browsers know to cache content (html,css,js,etc) when not explicitly instructed to do so


I was looking at Chirpy for css/js minifying,compression, etc. I noticed it doesn't support caching. It doesn't have any logic for sending expires headers, etags, etc.

The absence of this feature made me question if caching content is not as much of a concern; YSlow! grades this so I'm a little confused. Now I'm researching caching and cannot explain why this css file, SuperFish.css, is being retrieved from cache.

  1. Visit http://www.weirdlover.com (developer of Chirpy)

    Initial Download

  2. Look at initial network track. Notice, there is no expiration header for SuperFish.css.

    First pull

  3. Revisit the page and inspect the network trace again. Now SuperFish.css is retrieved from cache.

    Cached image

Why is the SuperFish.css retrieved from cache upon revisiting the page? This happens even when I close all instances of chrome and then revisit the page.


Solution

  • This seems to fall with in the HTTP specification.

    13.4 Response Cacheability

    Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entry, MAY return it without validation if it is fresh

    13.2.2 Heuristic Expiration

    Since origin servers do not always provide explicit expiration times, HTTP caches typically assign heuristic expiration times, employing algorithms that use other header values (such as the Last-Modified time) to estimate a plausible expiration time.

    It would seem by not providing a cache-control header, and leaving out the expires header the client is free to use a heuristic to generate an expiry date and then caches the response based upon that.

    The presence of an etag has no effect on this since the etag is used to re-validate an expired cache entry, and in this case chrome considers the cached entry to be fresh (the same applies to last-modified), thus it hasn't yet expired.

    The general principle being if the origin server is concerned with freshness it should explicitly state it.