从输出缓存提供的页面中的静态资产刷新策略

Posted

技术标签:

【中文标题】从输出缓存提供的页面中的静态资产刷新策略【英文标题】:Static assets refresh strategy in page served from output cache 【发布时间】:2021-11-25 13:02:58 【问题描述】:

我有一个采用 ASPNET MVC5 构建的站点,该站点采用自定义输出缓存策略。我们使用 MongoDB 数据库来存储我们的缓存,它运行良好。网站感觉很快,即使在 APPPool 或服务器重新启动后,我们的缓存仍然存在。

拥有这样的持久缓存的问题是保持我们的静态资产(javascript/css 等)不会过时。当我们依赖框架的标准输出缓存时,没有问题,因为每次更新站点并重新启动应用程序池时缓存都会丢失。但是现在我们有了更多的持久缓存,我们需要想出一个策略来保持我们的静态资产新鲜。

我们的旧方法是将文件内容的哈希附加到查询字符串上,这样当内容更改时,查询字符串也会发生变化,浏览器会获取新文件。

但是现在,有了持久缓存,资产的 URL 将永远不会改变。在这种情况下保持资产新鲜的好策略是什么?我们的缓存中有超过 100,000 个页面,因此我们不希望每次对 CSS 或 JS 进行小的更改时都必须将它们全部删除并重新构建它们。

对于这种情况,有没有人有任何久经考验的解决方案?

【问题讨论】:

您是否考虑过将 etags 用于您的资源?就像使用哈希一样,但形式不需要您将其附加到 url。 你可以用不同的方式处理这个问题,最初,我认为有两个选择: 1. 如果从概念上你知道你的静态文件是不断变化的,你可以在 web.config 中定义刷新它们的平均时间。 2.你可以使用一个flag外观参数告诉浏览器重新加载资源(你不需要重命名文件)。示例:example.com/css?v=1,因为浏览器会认为这将是一个新请求,但您的服务器会忽略此参数。 【参考方案1】:

如 Rani Sharim 所述,考虑使用 ETags。 ETags 允许您提供在浏览器缓存中使用哪个版本的标识符。

ETag 有点像指纹,如果 ETag 在缓存中已知,它将从缓存中提供。如果 ETag 似乎未知,则会检索并缓存新版本。

我的建议是将 ETags 基于提交版本(如果文件在提交中被修改)。这样,您就可以确保资产始终保持新鲜,并且您的网站保持快速。未修改的资产仍将从缓存中提供,因为 ETag 将保持不变。

【讨论】:

Etags 是概念上的答案,但实际上它们似乎有点不稳定,例如,当我将站点配置为在 Firefox 中使用 Etags 时,我可以看到未更改的静态资产的 304 响应,但在 Chrome 中,很多时候我从缓存中得到 200 响应,所以它甚至不需要检查服务器,而其他时候它会按预期响应 304。我试图了解工作流程以更好地预测 Chrome 将如何响应 也许这个 *** 问题可能对此有所帮助:***.com/questions/43659756/… 是的,正如该线程所建议的那样,答案似乎可能是“缓存控制必须设置为无缓存”。这实际上是有道理的,并且在初始测试中,Chrome 和 FF 以一致的方式响应,每次都执行 304 检查。

以上是关于从输出缓存提供的页面中的静态资产刷新策略的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nginx 上使用高效的缓存策略服务静态资产?

检查 Angular SPA 视图更改的缓存清单更新

php利用ob缓存机制实现页面静态化方法全解

使用 symfony2 clear cache 命令不刷新静态资产

php输出控制函数和输出函数生成静态页面

ASP.NET Cache 实现依赖Oracle的缓存策略