Aggressive JavaScript Caching

I have a problem when I make changes to several JavaScript files that are referenced in an HTML file, but the browser does not see the changes. It is stored in a copy stored in the browser, although the web server has a newer version.

Until I force the browser to clear the cache, I see the changes.

Is this a web server configuration? Do I need my JavaScript files to never be cached? I saw some interesting methods in the Google Web Toolkit where they actually create the new JavaScript file name any time the update is done. I believe this prevents the use of proxy servers and browsers of older versions of JavaScript files with the same name.

Is there a list of best practices anywhere?

+20
javascript caching
Sep 10 '08 at 15:46
source share
10 answers

We add the product build number to the end of all Javascript (and CSS, etc.), for example:

<script src="MyScript.js?4.0.8243"> 

Browsers ignore everything after flagging the question, but the update calls a new URL, which means reloading the cache.

This has the added benefit that you can set HTTP headers that mean "never cache!"

+27
Sep 10 '08 at 15:49
source share

It is stored in a copy stored in the browser, although the web server has a newer version.

Perhaps this is because the HTTP Expires / Cache-Control headers are set.

http://developer.yahoo.com/performance/rules.html#expires

I wrote about it here:

http://www.codinghorror.com/blog/archives/000932.html

This is not bad advice, in fact, but it can cause huge problems if you are mistaken. For example, in Microsoft IIS, the Expires header is always disabled by default, probably for this reason. By setting the Expires header in HTTP resources, you tell the client that it will never check for new versions of this resource - at least until the Expires header expires. When I say "never", I mean - the browser will not even ask for a new version; it will simply assume that its cached version is good until the client flushes the cache or the cache reaches the expiration date. Yahoo notes that they change the file name of these resources when they are updated.

All that you really save is the cost of the client who pinged the server for the new version and received 304 the unchanged header back in the general case when the resource did not change. This is not much overhead .. unless you are Yahoo. Of course, if you have a set of images or scripts that almost never change, be sure to use client caching and enable the Cache-Control header. Caching is critical to browser performance; Every web developer should have a deep understanding of how HTTP caching works. But use it only in a surgical, limited way for those specific folders or files that might benefit. For everything else, risk outweighs the benefits. This, of course, is not what you want to include as the default by default for your entire site .. if you don't like changing the file names every time the content changes.

+9
Sep 10 '08 at 16:08
source share

@ Jason and Darren

IE6 treats anything with the query string as unencrypted. You should find another way to get the version number in the url, like a fake directory:

 <script src="/js/version/MyScript.js"/> 

and just delete this first directory level after js on the server side before executing the request.

EDIT: Sorry, everyone; this is Squid, not IE6, which will not cache the query string. More details here .

+7
Sep 10 '08 at 15:56
source share

I wrote a blog post about how we overcome this problem:

Avoiding JavaScript and CSS Caching Issues in ASP.NET

Basically, during development, you can add a random number to the query string after the file name of your CSS. When you build the release, the code switches to using the build version number. This means that in your working environment, your clients may cache the stylesheet, but whenever you release a new version of the site, they will be forced to reload the file.

+7
Jul 30 '09 at 20:00
source share

I am also a method of simply renaming things. It never fails, and it's pretty easy to do.

0
Sep 10 '08 at 15:48
source share

Does your web server send the correct headers to tell the browser that it has a new version? I also added a date to querystring. those. myscripts.js? date = 4/14/2008 12:45:03 (only the date will be encoded)

0
Sep 10 '08 at 15:51
source share

@ Darren A problem with caching occurred on both IIS 6 and Apache 2 out of the box. I'm not sure that the correct permission is to change the headers of the HTTP responses, but instead, go to the renaming route described in several answers here.

@Chris Good advice. I thought the query string approach was good, but it seems like a unique file or directory name is needed for all cases.

0
Sep 10 '08 at 16:02
source share

In each release, we simply add a monotonously increasing integer to the root path of all our static assets, which causes the client to reboot (we saw that the query string method was interrupted in IE6 before). For example:

  • Issue 1: http://www.foo.com/1/js/foo.js
  • Release 2: http://www.foo.com/2/js/foo.js

Each version requires link rewriting, but we have created functionality for automatically changing links in our deployment tools.

Once you do this, you can use the Expires / Cache-Control headers, which allow the client to cache JS resources β€œforever”, as the path changes with each version, which, in my opinion, is what @JasonCohen did.

0
Sep 10 '08 at 16:03
source share

Some very useful methods are here , even if you do not plan to use powershell to automate the deployment.

0
Sep 10 '08 at 16:08
source share

For what it's worth, I saw deviantART , quite large, serving their JS files like 54504.js. I just checked and see what they now serve them as v6core.css? -5855446573 v6core_jc.js? 4150339741 etc.

If the problem with the query string comes from the server, I suggest that you can control this more or less.

0
Nov 22 '08 at 9:47
source share



All Articles