为什么在文件名中包含散列更好地用于缓存而不是将时间戳作为查询参数附加?

时间:2014-08-28 20:40:35

标签: node.js caching gruntjs browser-cache revision

在使用Grunt构建时,我遇到了rev任务和cachebreaker任务,需要修改/缓存静态资产。

一个使用文件名覆盖,另一个使用时间戳作为查询参数。 And apparently, one is more preferable than the other.

为什么一个比另一个好?

1 个答案:

答案 0 :(得分:8)

您提供的链接中的一条评论说得最好:

"一旦你有了唯一的名字,你也可以使用非常积极的缓存标题,这对于提高性能非常有用。"

使用时间戳,您的示例中包含此版本:

<script type="text/javascript" src="@routes.Assets.at("javascripts/main.js")?nocache=@(new Date().getTime())"></script>

每次请求脚本时,它都会添加一个唯一的时间戳。这意味着浏览器从不缓存它。

替代方案,但类似的方法是添加内部计数器。像这样:

<script type="text/javascript" src="@routes.Assets.at("javascripts/main.js")?version=1234"></script>

这个更好一点 - 因为每次更改资产中的内容时,都会更改版本号。然后,浏览器只加载一次版本,并将其保存在缓存中,直到您构建新版本的静态资产。

缺点是您必须以某种方式跟踪版本号。你可以使用一些静态的东西,比如git commit的一部分,但是仍然会关注这个版本+然后你依赖于git(或svn或你使用的任何东西)。

哈希版本,例如 javascripts/main.ab4c6c83e4fa9c.js 具有以下好处:

  • 它只与一个文件相关 - 所以它只依赖于main.js.无论你在其他任务中使用什么,我们都关心main.js.您不关心日期或版本或任何事情。
  • 它仅与文件内容有关。因此,如果您更改了js代码,您将生成不同的内容(例如,来自缩小器),因此散列将是不同的。浏览器将被强制加载新版本。
  • 如果您再次将内容更改为与之前相同(不仅仅是恢复到该版本,而是在未来版本中也会出现同一点),则该内容的哈希值将与该内容的哈希值相同。浏览器已经在缓存中。

因此,有了这些,您就不会关心日期,文件,任何事情,只需创建您的Javascript即可。您还可以告诉浏览器将其缓存为一年,或者永久。并且您确定如果您在版本之间切换,则用户会获得正确的版本。