4

在处理网页时,客户端/浏览器决定是否更新图像或 .css 或 .js 之类的文件,或者是否从缓存中获取文件。

如果是 .aspx 页面,则由服务器决定。

当然,在 IIS 级别上或者也使用一些 HttpModule 技术,我可以更改请求的标头以告诉客户端是否应该缓存文件以及应该缓存多长时间。

现在,我确实有一个网站,其中 .aspx 与相应的 .js 携手并进。所以,也许我在 .js 中有一些 jQuery 代码可以访问 .aspx 中的元素。如果我从 .aspx 中删除该元素,我也会调整 .js。如果用户访问我的页面,他将获得新的 .aspx,但仍可能获得旧的 .js,从而产生有趣的效果。

我的网站使用大量脚本和大量图像。出于性能原因,我在 IIS 中配置这些文件“永不过期”。

现在,有时文件确实会更改,我想确保用户获得更新文件。

一开始,我通过重命名文件来帮助自己。所以,我有 SkriptV1.js 和 SkriptV2.js 等等。这是最糟糕的选择,因为存储库历史记录已损坏,我需要同时调整引用和文件名。

现在,我在此处进行了改进,并使用 Skript.js?v=1 或 Skript.js?v=2 仅更改了引用。这会强制客户端刷新文件。它工作正常,但我仍然必须调整参考。

现在,这里有一个进一步的改进,如下所示:

<script type='text/javascript' src='../scripts/<%# GetScriptLastModified("MyScript.js") %>'></script>

因此,“GetScriptLastModified”将附加 ?v= 参数,如下所示:

protected string GetScriptLastModified(string FileName)
{
    string File4Info = System.Threading.Thread.GetDomain().BaseDirectory + @"scripts\" + FileName;
    System.IO.FileInfo fileInfo = new System.IO.FileInfo(File4Info);
    return FileName + "?v=" + fileInfo.LastWriteTime.GetHashCode().ToString();
}

因此,呈现的 .js-Link 在客户端看起来像这样:

<script type='text/javascript' src='/scripts/GamesCharts.js?v=1377815076'></script>

每次上传新版本时,链接都会更改,我可以确保用户在更改时立即获得新的脚本或图像。

现在,有两个问题:a)有没有更优雅的方法来实现这一点?b) 如果不是:有人猜测服务器上的性能开销有多大?一页上很容易有 50 个版本化元素,因此对于一个 .aspx,GetScriptLastModified 将被调用 50 次。

期待讨论:)

4

1 回答 1

0

这个问题有几个不同的答案。

首先,如果您的文件每隔一段时间才会更改一次,请将 Expires 和 Cache-Control 标头设置为一年后过期。只有当文件真正永不过期时,您才应该说它们永不过期。您现在看到说“永不过期”的问题。

此外,如果您的网站因提供大量图像和 JavaScript 而出现性能问题,则普遍接受的解决方案是使用 CDN(内容交付网络)。有许多不同的供应商,我相信您可以找到符合您预算的供应商。从长远来看,您还将节省资金,因为 CDN 将从 IIS 卸载大量 I/O 和 CPU 时间。令人震惊的是它可以带来多大的改变。

最后,确保用户获得几乎永远不会更改的文件的最新版本的一种方法是在您的资产 URL 中实施某种版本控制方案,以使缓存失效发生。有许多不同的方法可以做到这一点,但一种(非常天真的)方法是让每次部署到您的站点时都会增加一个版本号。

例如,您所有的资产 URL 将看起来像 /static/123/img/dog_and_pony.jpg

然后,下次部署到站点时,增加版本号使其变为“124”。您需要一些方法来跟踪版本,将其动态注入资产 URL,并确保每次部署时版本号都会更改。这个想法是任何引用这个资产的东西都应该自动知道新的版本号。

在性能方面,永远不需要用户刷新或下载相同的东西两次是一个令人钦佩的目标。但有时它只是少了很多麻烦,如果用户只是定期刷新所有内容,这对大多数网站来说可能没问题。

希望这可以帮助。

于 2012-04-15T06:41:58.063 回答