防止过时的CSS和JavaScript的最佳实践是什么

防止过时的CSS和JavaScript的最佳实践是什么,javascript,css,spring-mvc,amazon-s3,Javascript,Css,Spring Mvc,Amazon S3,我正在为一个项目研究这个问题,我想知道其他人在做什么来防止过时的CSS和JavaScript文件与每个新版本一起使用。我不想附加时间戳或类似的东西,这可能会阻止对每个请求进行缓存 我正在使用Spring2.5MVC框架,并且已经在使用GoogleAPI为prototype和scriptaculous提供服务。我也在考虑使用Amazon S3和新的Cloudfront产品来最小化网络延迟。如果修改了标题,请使用条件get请求,这实际上是一个非常困难的问题,您可以花一些时间来设计正确的解决方案 我建

我正在为一个项目研究这个问题,我想知道其他人在做什么来防止过时的CSS和JavaScript文件与每个新版本一起使用。我不想附加时间戳或类似的东西,这可能会阻止对每个请求进行缓存


我正在使用Spring2.5MVC框架,并且已经在使用GoogleAPI为prototype和scriptaculous提供服务。我也在考虑使用Amazon S3和新的Cloudfront产品来最小化网络延迟。

如果修改了
标题,请使用
条件get
请求,这实际上是一个非常困难的问题,您可以花一些时间来设计正确的解决方案

我建议使用url中内置的时间戳和/或版本发布文件,而不是:

/media/js/my.js您最终得到:

/media/js/v12/my.js或类似文件

您可以使用任何工具自动化版本控制/时间戳

这样做的另一个好处是在推出新版本时不会破坏站点,并允许您进行真正的并行测试(不同于只剥离版本并发回最新文件的重写规则)

使用JS或CSS需要注意的一件事是,当您在其中包含依赖的URL(背景图像等)时,您需要确保JS/CSS时间戳/版本在其中的资源发生更改时发生更改(以及重写它们,但使用非常简单的正则表达式和资源清单是可能的)


无论您做什么,请确保最后不要抛出一个?vblah,因为这样做基本上就是将缓存抛出窗口(不幸的是,这是迄今为止最简单的处理方法)

我在请求中添加了一个带有修订号的参数,类似于:

<script type="text/javascript" src="/path/to/script.js?ver=456"></script>

“ver”参数随每个生成自动更新(从生成更新的文件读取)。这将确保仅为当前版本缓存脚本。

如果您将文件的“修改时间”作为时间戳,它将被缓存,直到文件被修改为止。只需使用helper函数(或其他框架中调用的任何函数)添加脚本/css/image标记,从文件中获取时间戳。在类unix系统(大多数情况下都是这样)上,您只需
触摸
文件,就可以在必要时强制更改修改的时间


RubyonRails在生产模式下使用此策略(默认情况下,我是beleave),在开发模式下使用正常的时间戳(以确保某些东西没有被缓存)。

关于缓存文件,我还没有通过使用querystring方法遇到任何与过时缓存文件相关的bug问题

但是,关于性能,以及重复提到的按文件名加速,请查看Steve Souders的工作,了解更多关于该主题的信息:

“Squid是一种流行的代理,它不使用查询字符串缓存资源。如果代理缓存后的多个用户请求同一个文件,而不是使用缓存版本,则每个人都必须向源服务器发送请求,这会影响性能。”

代理管理员可以更改配置以支持使用querystring缓存资源,当缓存头表明这是合适的。但是默认配置是web开发人员最常遇到的配置


与@eran galperin一样,我在对JS文件的引用中使用了一个参数,但我包含了一个服务器生成的对文件“上次修改”日期的引用@斯特林豪格提出了这种方法。它看起来像这样:


服务器会忽略静态文件的参数,客户端可能会缓存脚本,直到日期代码更改为止。如果(且仅当)修改服务器上的JS文件,日期代码将自动更改

例如,在PHP中,我创建此代码的脚本如下所示:

函数cachePreventCode($filename){
如果(!file_存在($filename))
返回“”;
$mtime=filemtime($filename);
返回$mtime;
}
因此,当PHP文件包含对CSS文件的引用时,它可能如下所示:


如果您使用MAVEN,您可以在pom.xml上添加以下内容:

<properties>
   <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
   <timestamp>${maven.build.timestamp}</timestamp>
</properties>

yyyyMMddHHmm
${maven.build.timestamp}
有了它,您可以在视图中访问${timestamp}。 就像这个例子:

<script type="text/javascript" src="/js/myScript.js?t=${timestamp}"></script>


最好的解决方案是最简单的:)谢谢很多旧的代理会拒绝缓存任何带有查询字符串的内容。最好使用某种绑定器将该id工作到文件名中
/path/to/script-456.js
要好得多。更容易使用,
/path/to/v456/script.js