什么是防止陈旧的CSS和JavaScript的最佳实践

时间:2008-12-10 15:53:47

标签: javascript css spring-mvc amazon-s3

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

我正在使用Spring 2.5 MVC框架,我已经在使用google api来提供原型和scriptaculous。我还在考虑使用Amazon S3和新的Cloudfront产品来最大限度地减少网络延迟。

6 个答案:

答案 0 :(得分:14)

我使用修订号在请求中添加一个参数,例如:

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

每次构建时都会自动更新'ver'参数(从文件读取,构建更新)。这可确保脚本仅缓存当前版本。

答案 1 :(得分:4)

与@ eran-galperin一样,我在JS文件的引用中使用了一个参数,但是我在文件的“上次修改”日期中包含了服务器生成的引用。 @ stein-g-strindhaug建议采用这种方法。它看起来像这样:

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

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

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

function cachePreventCode($filename) {
    if (!file_exists($filename))
        return "";
    $mtime = filemtime($filename);
    return $mtime;
}

那么当你的PHP文件包含对CSS文件的引用时,它可能如下所示:

<link rel="stylesheet" type="text/css" href="main.css?<?= cachePreventCode("main.css") ?>" />

......这将创造......

<link rel="stylesheet" type="text/css" href="main.css?1347489244" />

答案 2 :(得分:2)

关于缓存文件,我还没有使用查询字符串方法遇到任何与陈旧缓存文件相关的错误问题。

然而,关于性能,并回应Todd B提到按文件名加速,请查看Steve Souders关于该主题的更多信息:

“Squid是一种流行的代理,它不会使用查询字符串来缓存资源。当代理缓存后面的多个用户请求相同的文件时,这会损害性能 - 而不是使用缓存版本,每个人都必须发送请求到原始服务器。“

“当缓存标头指示合适时,代理管理员可以更改配置以使用查询字符串来支持缓存资源。但默认配置是Web开发人员应该最常遇到的。”

http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/

答案 3 :(得分:1)

这实际上是一个非常棘手的问题,您可以花一些时间来设计正确的解决方案。

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

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

/media/js/v12/my.js或类似的东西。

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

这具有额外的好处,即在推出新版本时不会破坏网站,并允许您进行真正的并排测试(与仅剥离版本并发回最新文件的重写规则不同)。 / p>

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

无论你做什么,都要确保不要在最后扔掉一个vblah,因为当你这么做的时候你基本上就是把窗户放在窗外(这是不幸的,因为它是迄今为止处理这个问题的最简单方法)

答案 4 :(得分:1)

使用带有conditional get标题

If-Modified-Since个请求

答案 5 :(得分:0)

如果您将文件的“修改时间”作为时间戳,它将被缓存,直到文件被修改。只需使用辅助函数(或其他框架中调用的任何函数)来添加从文件中获取时间戳的脚本/ css / image标记。在类似unix的系统上(大多数人都是),你可以简单地touch文件来强制修改时间在必要时进行更改。

Ruby on Rails在生产模式下使用此策略(默认情况下为beleave),并在开发模式下使用正常时间戳(确实无法缓存某些内容)。