views:

785

answers:

7

Currently browsers have incomplete caching implementation. It only allows to set expiration or keep immediate expiration. Important 3rd option to expire cache programmatically is missing. Without that 3rd option developers cannot deploy new version of code efficiently and reliably.

If they use 2nd option it is inefficient if they have framework of many small files. Combining many small files into one is not efficient because any small change will cause whole framework to be deployed instead of one single file.

If they use 1st option updates will not get to user until cache expiration which creates compatibility problems between server side code and client side code and potentially between different parts of client side code. Setting expiration requires prediction of future deployment, which is inconvenient and will disallow quick bug fixes.

When people ask about that problem, some suggest to use version numbers or other temporary ids to trick browser cache by loading unique URLs. The problem with it is that it puts unnecessary overhead on network and local file system to load and store unnecessary old versions and tons of unique URLs. It almost defeats the purpose of caching by URL. The right solution is to allow programmer of a web site to clean cache of files that came only from that web site. That way list of updated files could be requested and cache of newer files would be cleaned to allow browser to load fresh versions.

Proper caching mechanism is simple and powerful pattern that could boost all web client-side development to new levels, I only wonder why browser producers did not implement it yet.

+4  A: 

Hehe, well, as far as us developers are concerned, of course!

On the other hand, cache is there to facilitate the user's experience in terms of responsiveness. It is our responsibility to work-around all these nuisances and protect the user in a shell of ignorance and all-is-wellness.

Nikolaos
Very well stated!
Mike Clark
The problem is that browsers made it impossible for us to "work-around all these nuisances". If browsers stop supporting JavaScript one day, will you say that it's our responsibility to create rich web user interface without use of JavaScript ?
alpav
A: 

they theorically do, with cache params in the header section and meta parameters (google meta no-cache, PHP/ASP no-cache) like cache-expires, the date that should expire etc

I agree that this is weird in most, if not all, browsers. sometimes it works, sometimes it doesn't or takes more time to clear the cache for some reason

but would be nice to have that option in the script, like a javascript or something directly on the tags, like img src="blah.jpg" expires="my_blah_last_edited"

it could be better, true

Jonathan
alpav
+2  A: 

I do not think it is this easy. One problem I can see is that it is not just the browser cache. your files can be cached in many places along the way from your server to the browser (clients). Some of the browsers can still use the old version, and the answer to the question which one is cleared and what version is supposed to go to this particular client becomes really uncertain really fast.

mfeingold
Will it be easy and viable if browsers stop relying on any intermediate caching and introduce special cache-control mode "client-cache" which would mean immediate expiration on server and all intermediate layers, but stay cached on browser level ?
alpav
+2  A: 

It's an interesting idea, but how would the browser know when to ask your website if it should clear the cache? Every time the page is loaded? Wouldn't that partially defeat the purpose of caching? Set reasonable cache expiration intervals, and schedule your updates to match those, and it should be ok as it is.

luvieere
I think this is the only answer that addresses the real problem with the question: how can you program the cache to do anything if the program has to be downloaded first?!?
Jeff Meatball Yang
By using component loader and coding web app as one page application. See my more detailed response on top.
alpav
@alpav Not a very SEO-friendly aproach there, makes indexing and navigation a bit difficult.
luvieere
I agree about SEO. It does not have to be one page app, the idea is that every file does not have to ever expire except the list of updated files. If main loader is in expired list then whole app reloads. Users should never be required to clear cache manually or click refresh to get fresh software version.
alpav
@luvieere: "schedule your updates" is the problem that prevents developers from quick painless updates. Schedule is painful because once you updated there is no way to update again until next scheduled point of time and if you've made mistake there is no solution to fix it.
alpav
A: 

I imagine there are great security concerns. You have anonymous and remote web-pages telling local a client to delete files on the client machine - this has all sorts of potential for disaster. Would you trust IE to do this? It just sounds too risky. There's a big difference between a directive to not cache something in the first place and a directive to delete something already in existence from the cache.

Dan Diplo
No, there are no security concerns. Pages will not tell which file in which folder to delete, they will tell which URL to expire immediately. How setting immediate expiration on any URL after it's loaded can be security concern ?
alpav
+1  A: 

I don't think what you suggest is necessary or desirable.

The client-side cache should be controlled by the user, not by you (the data/code provider). If the user wants a better way to manage his "Temporary Internet Files", then that's up to the browser developers, but I think you should not have a say in how it is managed.

For all intents and purposes, you only need to say, "this data/code is usable until X date", "this data/code is usable until Y version", or "it's never usable again".

Excellent cache control strategies can already be setup by using the existing HTTP headers (Cache-Control, ETag, etc.). If you want something to be "forced" to be refreshed, you can always add a querystring with the date on it. This is not really a hack, as you suggest, because you are saying, "get me the version of the file as of this date"... and your server has all the freedom in the world to refresh the caching policy: return "302 redirect" to the non-querystring version, or send down new headers, etc.

Edit:

I can refine my idea from above:

You can use a path or querystring to identify the "current" version:

http://somedomain.com/somepath/current/yourfile.js

The "current" URL can be setup to give a 302 redirect to a particular version of yourfile.js, while also telling the browser never to cache the current version:

302 Moved Temporarily
Location: /somepath/v3.2.3/yourfile.js
Cache-Control: no-cache;

This allows your "loader" HTML to include Javascript that decides to use a certain version:

<script type="text/javascript">
<%php
   if($action == "clearCache") {
        print "var version = 'current';";
   } else {
        print "var version = '" . $version . "';";
   }
%>
</script>
Jeff Meatball Yang
302 redirect is interesting solution if it works without duplicating files in browser or proxy cache. But it still must duplicate URLs inside cache to avoid sending request every time page is loaded. Also it requires making dynamic references (URLs with querystring parameters) when my idea allows to keep static references just like they are on most web pages today.
alpav
I disagree that developers "should not have a say in how it is managed". Developers have a say already because they can set immediate expiration or set indefinite expiration and generate tons of unique links and overload any local or proxy cache with garbage.I see that I made mistake in my question saying "clear cache programmatically" instead of "expire cache programmatically", which is what I really meant.
alpav
A: 

Why not embed some kind of unique tag or timestamp in the image etc. uri for each deployment, thereby causing the browser to reload?

Kiffin
Because that exhausts caching resources if number of updates is significant.
alpav