Hello, this is Jan Lehnardt and you're visiting my blog. Thanks for stopping by.
plok — It reads like a blog, but it sounds harder!
↑ Archives
This is a small trick and it is, conceptually not new. It is common practice to add version numbers to resource files of a website. These are image-, CSS- and Javascript files. The reason to do so is to make sure users do get new versions of the files when you change them instead of when their browser decides to flush its cache. And you certainly don’t want to tell your visitors to do a shift-reload for each small update you do. So you could do something like
<script type="text/javascript" charset="utf-8" src="prototype1.50.js"></script>
and update the version number whenever you change things. This is a maintenance nightmare, though, because you’ll have multiple versions of the same file lingering around next to each other and all the beauty of version control (You do use it, right?) is lost.
What you can do instead, is adding a GET-parameter to the filename, like this
<script type="text/javascript" charset="utf-8" src="prototype.js?150"></script>
and update the version number whenever you change things. This is a different maintenance nightmare because you have to update all resources and keep track of the changes. This can be scripted, but for small project it sure is overkill.
For the latest small project I tried to find a good solution that I could set up and didn’t have to worry about. I looked into parsing out the SVN revision and attach it, but that’s not a fun thing to do. Besides, the actual version is not important here, just a different number for each version. Here’s what I do (using PHP, this can be easily done in any other scripting language)
<script type="text/javascript" charset="utf-8" src="prototype.js?<?=filemtime("prototype.js");"></script>
This updates the variable parameter whenever the file changes. It is deployed and I don’t have to worry about out-of-date data anymore.
If you’re in a high-speed environment, you don’t actually want to do several fstat()
s per request, but you’ll have some caching mechanism in place anyway.
You might also be interested in this: http://www.thinkvitamin.com/features/webapps/serving-javascript-fast (scroll down to "Mistakes abound")
We did something similar to this, but then it was pointed out that some browsers dont cache any object with a ? in the url, so this might not work out as well as thought.
We have since done it with a rewrite rule like suggested, which works much better. (still only one file, but it the url can change when the file does, but apache should handle the headers correctly) - seems to work well :)
Barry,
Modern browsers (99.9%) listen to HTTP cache headers, regardless of the url..
Jan,
You are probably looking for filemtime, instead of filectime. filectime will update if you change the inode (different permission, owner, etc.) but filemtime updates if the actual contents change.
Evert
Hey Evert, that was meant to be filemtime() and it probably is the worst typo to be made in this post. Well spotted and thanks for the comment!
Cheers,
Jan