Prevent Your CSS and JavaScript Files From Being Cached

By  on  

Some websites use highly volatile, oft-changing CSS and JavaScript files. In the case of these files, it's important that the developer prevent browsers from caching them. How do we do that? By using a phantom querystring, of course. We'll use PHP to tack the current time onto the file reference.

The PHP

<link href="/stylesheet.css?<?php echo time(); ?>" rel="stylesheet" type="text/css" /&glt;
<-- RENDERS -->
<link href="/stylesheet.css?1234567890" rel="stylesheet" type="text/css" /&glt;
<script type="text/javascript" src="/site-script.js?<?php echo time(); ?>"></script>
<-- RENDERS -->
<script type="text/javascript" src="/site-script.js?1234567890"></script>

It's a very simple technique and doesn't affect your CSS or JavaScript code in any way.

Recent Features

  • By
    5 Ways that CSS and JavaScript Interact That You May Not Know About

    CSS and JavaScript:  the lines seemingly get blurred by each browser release.  They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely.  We have our .js files and our .css, but...

  • By
    An Interview with Eric Meyer

    Your early CSS books were instrumental in pushing my love for front end technologies. What was it about CSS that you fell in love with and drove you to write about it? At first blush, it was the simplicity of it as compared to the table-and-spacer...

Incredible Demos

  • By
    Send Email Notifications for Broken Images Using jQuery AJAX

    It's usually best to repair broken image paths as soon as possible because they can damage a website's credibility. And even worse is having a user tell you about it. Using jQuery and PHP, you can have your page automatically notify you of broken...

  • By
    Full Width Textareas

    Working with textarea widths can be painful if you want the textarea to span 100% width.  Why painful?  Because if the textarea's containing element has padding, your "width:100%" textarea will likely stretch outside of the parent container -- a frustrating prospect to say the least.  Luckily...

Discussion

  1. Great tip! I never even thought of doing something like that to prevent caching.

  2. Catar4x

    On a spanish blog, I saw this function a long time ago :

    function version($file) {return $file.'?'.filemtime($file);}
    But, thanks for the javascript tip !

  3. Catar4x: Ooooh, I like that even more.

  4. I covered what Catar4x posted some time back:
    http://www.electrictoolbox.com/javascript-css-file-timestamps/

    It’s a little wordy but covers the thinking behind it.

  5. and doesn’t effect your CSS

    is supposed to be:

    and doesn’t affect your CSS

    On a more related note, I use a modified php script I found here: http://www.ejeliot.com/blog/72

    The script (as I’ve modified it) always produces the latest js and css, and then caches that until one of the included js or css files change.

  6. I often need to add a random query string after a resource when grabbing something via Ajax, because IE will try to cache all sorts of weird stuff.

    Excellent tip, Walsh.

  7. @Eric add a no cache header to your ajax response.

    netvibes uses a version number based off their svn revision, just something else to consider.

  8. Heed the words of Souders!

    • Brett

      Sometimes using this method is a requirement, such as ensuring a user gets the correct file for the release version. I have done this by including sFileSrc + “?v” + SiteVersion. Dueing debug, to avoid caching this is simply replaced by a timestamp to ensure every load has the most recent copy of the file.

    • Brett

      *During debug, not Dueing

  9. As Zach points out, you shouldn’t use query strings to “bust caches”. Check out my Juicer project for a more complete solution. Combined with a far future expires header you’ll have a winning combination :)

  10. David

    Is there a way to do this in Coldfusion?

  11. Nacho

    I use names like myfile.v2.ext to all my static content and rename it to myfile.ext with mod_rewrite in Apache.
    Every time i change the script I increase the version number.
    no need to avoid caches

  12. How I started doing Javascript caching:

    Bundle all javascript calls automatically into 1 source, for example:

    bundle.js?js=js/mootools-core.js,js/mootools-more.js,js/run.js&m=17274278

    Where $_GET[‘js’] is a comma separated list of scripts, and $_GET[‘m’] is the sum of all modification-dates (to prevent caching, as you describe in your article, but using filemtime() instead of time() and sum it to account for all files)

    bundle.js is rewritten using .htaccess to bundle.php which takes care of concatenating, JSMinify-ing (!!) and caching of the javascript files. Additionally it implements request/response headers like etag and modified enabling me to even respond with header 304 (not modified)

  13. I really like Nacho’s idea and you could easily enough make a single rule so you don’t need to keep modifying the rule along the lines of this (untested, off the top of my head):

    RewriteRule /css/main.[0-9]+.css /css/main.css

    Then the css in the code looks something like this: /css/main.1189482039.css and you could use PHP etc to work out the timestamp based on the modification time, which I’ve posted about previously (see my earlier link in the comments). Then you never need to change anything manually.

    I’m going to write up a post about this on my blog tomorrow.

  14. I’ve also found that doing this works well with mobile development as I’ve encountered content pages caching often.

    For the ColdFusion fix you could do something like:

    <cfoutput>#timeFormat(now(),’hhmmssL’)#</cfoutput>

  15. James

    How about using .htaccess for disabling js/css caching?

    <FilesMatch “\.(js|css)$”>
    Header unset Cache-Control
    </FilesMatch>

  16. The catch with not caching JS or CSS at all is that the browser is going to have to download a copy of the file(s) every single time you load a page. This will slow requests down etc so it’s better to use some other convention as other people have suggested here e.g. using a query string with the timestamp (which appears to be not particularly recommended due to proxy issues) or the version number in the filename.

    If you’re going to make the browser download the CSS/JS every time then you may as well just include it in the page itself so only one request needs to be made per page.

  17. As I mentioned in an earlier comment, I was going to write a post about using rewrite rules etc. You can read it here: http://www.electrictoolbox.com/force-reload-css-javascript-unique-filenames/

  18. Nacho

    You can go a step further by having a table with the MD5 of all your static content. Every time you make new changes, a script checks the MD5 of all files and if it changes, adds +1 to the version number.
    then generate all URLs with a function that appends the version of this table to the filename so you dont have to do anything

  19. But why are you address the problem at php level? Apache (and all the servers that implements ETags) returns a 304 Not Modified http header if the file is old, and the correct response if file is modified (for Apache basing on modification date, inode, etc.).

  20. So that’s mean the string after ? on .css file … i’ve seen that on wordpress blog …

  21. Jason Arencibia

    I know this is old, but I just found the site reading up on jQuery and mootools and since I’m not the best with JS, I tend to have to change things a lot and caching can become an issue where your asking yourself did I upload that last change? lol

    adding the query string to files might be a simple way, but I thought I’d share what I have done! seems to work!

    I just turn all my javascript and css into php files and add this to the top of the file:

    then call it like this in the page header

  22. Man you’ve really assisted me.

    Your solution is great.

    Keep up the good job.

    I am a young developer concentrating of PHP Ajax applications.

    I prefer to use JQuery Javascript framework.

  23. kash

    this is a great solution thanks, but, i dont understand how to implement it, if i just want to stop javascript from being cached do i just paste this somewhere on my site head or very top:

    <script type="text/javascript" src="/site-script.js?">

    And, where on the code it says 'site-script.js' -is that where i put the name of the javascript i want it to stop caching? and what are these numbers for: "/site-script.js?1234567890"?

  24. kash

    the code didnt paste properly, its the 2nd code on top if this page.

  25. Big up!

    Thanks for the tip.

    I was totally freak out with Chrome cache.

    Cheers.

  26. It’s a good tip but you have to download the entire css and js each page of the website you are surfing. I don’t think it’s the best solution.
    Maybe you can add a parameter like a version number after the question mark and change it only when the css/js really change. What do you think?

  27. thank you for this nice post

  28. Just want to say thanks for the tip. This saved me from further self mutilation.

  29. Chris

    Temporary Internet Files just caches the file with the date extension eg class.css?1304526

    I want to prevent any caching!

  30. Thanks for the tip! Done it using javascript as well

    • Hi Jayson, could you please post an example of how you accomplished this using JavaScript?

  31. Andrew

    Chis is absolutely right!
    just appending a random string just creates another cache entry…
    to test: empty your cache and see how it fills up.
    Headers are often ignored or only work (cache entry is deleted) once the browser is closed and not every browser interprets header directives the same way.
    As I said before empty your cache and see what is cached and whether you can read/extract it from the cache.

  32. Nice trick. But I’ve one question. I’ve included many js/jquery files as well as css files in my application. So is this affect on performance of my application ? because everytime it will force browser to load the latest js/css files.

  33. I’m not gay, but if I were, I could fall for a guy like you. THIS IS GENIUS.

  34. I would not advise you to do this, because you actually WANT your .js files to be cached. You only want to enforce an update, if there was a change. So, using a php-time function for generating query strings is surely not the best idea, since it creates a lot of unnecessary traffic. Also, filemtime is not the best idea, as it is slow. Still, i’d probably prefer this approach. Best is to use some deployment tool that takes care of updating the query string for files that changed.

  35. For cached there .htaccess. Which set rule for cached, what file will be cached and how long.

    If you dont have .htaccess, CSS or JS will not be cached.

    There is some text about .htaccess cached -> http://www.limecanvas.com/speed-up-your-website-using-caching-and-htaccess/

  36. Frank Meier

    Chris Hope:
    First at all a huge Thank you to clear this question!
    It is a big help what I could read here.
    The article from you and specially after it the discussion in which you are also involved.

    About your “The catch with not caching JS or CSS at all is that the browser is going to have to download a copy of the file(s) every single time you load a page.” ….

    This non caching is of course not for the end version of the page, but for test versions to see that all changed modules running correct.

    Again, Thank you very much!!!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!