帮助进行积极的JavaScript缓存
我遇到了一个问题,即我对HTML文件中引用的一些JavaScript文件进行了更改,但浏览器看不到这些更改。即使Web服务器具有较新的版本,它也保留在浏览器中缓存的副本中。
直到我强迫浏览器清除缓存后,我才能看到更改。
这是Web服务器配置吗?是否需要将JavaScript文件设置为从不缓存?我在Google Web Toolkit中看到了一些有趣的技术,它们在每次进行更新时实际上都会创建一个新的JavaScript文件名。我相信这是为了防止代理和浏览器保留具有相同名称的旧版本的JavaScript文件。
是否有最佳实践清单?
解决方案
回答
我也只是重命名。它永远不会失败,而且很容易做到。
回答
我们将产品内部版本号添加到所有Javascript(和CSS等)的末尾,如下所示:
<script src="MyScript.js?4.0.8243">
浏览器会忽略问号后的所有内容,但升级会导致产生一个新的URL,这意味着重新加载缓存。
这还有一个额外的好处,就是我们可以设置表示"永不缓存!"的HTTP标头。
回答
网络服务器是否发送了正确的标头,以告知浏览器它具有新版本?我也已经在查询字符串中添加了日期。即myscripts.js?date = 4/14/2008 12:45:03(仅对日期进行编码)
回答
@杰森和达伦
IE6将带有查询字符串的任何内容都视为不可缓存。我们应该找到将版本号输入url的另一种方法,例如伪造目录:
<script src="/js/version/MyScript.js"/>
并在完成请求之前在服务器端js之后删除该第一个目录级别。
编辑:对不起所有;不会使用查询字符串缓存的是Squid,而不是IE6. 更多信息在这里。
回答
@Darren现成的IIS 6和Apache 2都发生了缓存问题。我不确定是否正确的解决方案是修改HTTP响应标头,而是采用此处一些响应中所述的重命名路由。
@克里斯好提示。我认为查询字符串方法是一种很好的方法,但是听起来所有情况都需要一个唯一的文件或者目录名称。
回答
在每个发行版中,我们都简单地在所有静态资产的根路径前添加一个单调递增的整数,这将强制客户端重新加载(我们之前已经在IE6中看到查询字符串方法中断)。例如:
- 版本1:http://www.foo.com/1/js/foo.js
- 版本2:http://www.foo.com/2/js/foo.js
它要求每个发行版重新链接,但是我们已经建立了自动将链接更改为部署工具的功能。
完成此操作后,我们可以使用Expires / Cache-Control标头,让客户端"永远"缓存JS资源,因为该路径随每个发行版而变化,我认为这就是@JasonCohen的意思。
回答
It holds onto the copy cached in the browser, even though the web server has a newer version.
这可能是因为设置了HTTP Expires / Cache-Control标头。
http://developer.yahoo.com/performance/rules.html#expires
我在这里写过:
http://www.codinghorror.com/blog/archives/000932.html
This isn't bad advice, per se, but it can cause huge problems if you get it wrong. In Microsoft's IIS, for example, the Expires header is always turned off by default, probably for that very reason. By setting an Expires header on HTTP resources, you're telling the client to never check for new versions of that resource -- at least not until the expiration date on the Expires header. When I say never, I mean it -- the browser won't even ask for a new version; it'll just assume its cached version is good to go until the client clears the cache, or the cache reaches the expiration date. Yahoo notes that they change the filename of these resources when they need them refreshed. All you're really saving here is the cost of the client pinging the server for a new version and getting a 304 not modified header back in the common case that the resource hasn't changed. That's not much overhead.. unless you're Yahoo. Sure, if you have a set of images or scripts that almost never change, definitely exploit client caching and turn on the Cache-Control header. Caching is critical to browser performance; every web developer should have a deep understanding of how HTTP caching works. But only use it in a surgical, limited way for those specific folders or files that can benefit. For anything else, the risk outweighs the benefit. It's certainly not something you want turned on as a blanket default for your entire website.. unless you like changing filenames every time the content changes.
回答
即使我们不打算使用Powershell来自动化部署,此处的一些非常有用的技术也是如此。
回答
值得一看的是,我看到了deviantART网站,这是一个很大的网站,其JS文件为54504.js。我刚刚检查了一下,发现它们现在充当v6core.css?-5855446573 v6core_jc.js?4150339741等。
如果查询字符串的问题来自服务器,我想我们可以或者多或者少地控制它。
回答
我写了一篇关于我们如何克服此问题的博客文章:
避免ASP.NET中的JavaScript和CSS样式表缓存问题
基本上,在开发过程中,我们可以在CSS文件名之后的查询字符串中添加随机数。执行发行版本时,代码将切换为使用程序集的修订号。这意味着在生产环境中,客户端可以缓存样式表,但是每当我们发布网站的新版本时,它们都将被迫重新加载文件。