在apache中控制浏览器缓存更改js和css文件的最佳方法?

2023-12-03

我们刚刚对网站进行了重新设计,在部署之后,我们必须对控制新外观和感觉的各种 css 和 javascript 文件进行一些小调整。我们遇到的问题之一是浏览器似乎缓存了这些文件,因此用户客户端可能看不到我们所做的一些修复。
我们最初想对文件的 mtime 做一些事情,作为“快速修复”黑客,我们使用 url 参数修改了对这些文件的一些主要调用,该参数使用服务器端 php 附加相关文件的最新 mtime 。但这并没有按计划工作,因为我们的部署系统克隆了一个 git 分支,因此,每个部署最终都会触及每个文件并改变其运行时间。 (最终结果是,部署一个小修复最终会告诉客户端浏览器重新加载每个<LINK> or <Script>部署后修改标记,无论文件内容是否实际更改。)

我正在查看 apache FileETag,但它似乎使用 mtime、大小和 inode。 (我希望找到类似校验和的东西)mtime 显然不适用于我们使用的部署方法,如果更改不改变文件的长度,则大小可能不会改变。我不太熟悉索引节点信息的工作原理,所以我不确定这是否符合我们的需求。

所以我想知道是否有人还有其他建议,告诉客户端浏览器仅在文件内容实际更改时重新加载文件。


因此,人们经常混淆缓存的两个重要区别:

  1. 浏览器应该缓存资源多长时间。这通常是由 Cache-Control 标头驱动的(尽管有时也仍然使用旧的 Expires 标头)。在此期间,不会向服务器发出任何请求,直到资源被视为旧的。这是您尽可能想要的,因为它可以避免由带宽和延迟引起的问题。

  2. 应该如何重新验证过期资源。这是由 Last-Modified 或 ETag 标头驱动的。这里有一个请求is向服务器发出请求,服务器返回 304 响应,表示“我不会向您发送该文件的新版本,因为根据您提供给我的上次修改或 ETag 详细信息,您仍然拥有的副本仍然是最新的版本,所以认为这对另一位有好处”。这实际上只对大型资源(例如大图像或视频)有用。 CSS 和 JS 文件通常较小,下载它们的时间并不比发送 304 响应多多少,因此在这里使用 304 并没有真正获得太多好处。获得该信息的延迟any从服务器返回的响应(无论是 304 还是资源本身)是主要瓶颈,只能通过将文件在缓存中保留更长时间来避免。

您似乎想使用一些验证技术(修改时间或 ETag)来为您提供良好的缓存,但当您确实更改某些内容时会立即重新加载,但这不是最好的方法,因为您基本上只能在它是时使用上面的第二部分首先这会给你带来好处。顺便说一句,关于为什么延迟是问题的好文章:http://www.nateberkopec.com/2015/11/05/page-weight-doesnt-matter.html。该文章中还有很多其他很好的信息,因此建议您全部阅读。

因此,您最终需要非常长的 Cache-Controls,因此在第一次下载后它会保留在缓存中。但是,当您进行更改时,您希望强制用户尽快重新加载。这些是相反的要求。

因此,您的选择是要么使用缓存清除技术,要么基本上忽略该问题。

缓存清除技术基本上会欺骗浏览器,使其认为它正在请求不同的资源。例如在 URL 中添加参数。 CSS 技巧在这里有一个关于各种技术的很棒的页面:https://css-tricks.com/strategies-for-cache-busting-css/。基于您的部署技术无法基于 mtime 工作,因此您确实需要在此处添加版本号,但这有多容易取决于您创建页面的方式以及您使用的构建过程。

另一种选择是忽略该问题,直到资源过期。这可能看起来很奇怪,但越来越成为我的首选选择,所以让我解释一下原因。我所做的是建立一个非常short易于更改的关键资源(例如 HTML、CSS 和 JS)的到期时间。假设一到三个小时。然后接受人们将在这段时间内获得缓存的、可能过时的资源。大多数建议都是针对long过期时间希望将您的页面缓存一段时间,但考虑到缓存并不像某些人想象的那么大(再次参见上面引用的文章)恕我直言,除了非常频繁的访客之外,这种好处大多看不到。因此,您会遇到长期到期的麻烦,但没有任何好处。使用较短的有效期有几个好处:

  • 没有复杂的缓存清除
  • 除非访问者最近访问过,否则在缓存过期时间内,他们将获得最新的资源。
  • 您现在也可以缓存静态页面。大多数缓存清除技术取决于每次下载的 HTML(因此您可以检查页面所需的资源是否使用了任何缓存清除技术),但如果浏览到主页,然后浏览另一个页面,然后多次返回主页那么每次都下载主页就没有意义了!为什么不缓存它并在浏览时具有即时响应能力?除非您是新闻网站,否则 99% 的情况下都可能会使用旧主页。使用较短的过期时间可以让您缓存 HTML 页面。
  • 每次初始访问可能会较慢,但一旦不再妨碍,它将缓存资源并感觉快速浏览(假设页面共享大量资源)。现在,最初的页面加载很重要 - 不要误会我的意思,但是考虑到缓存大小,无论如何,这种额外的负面影响都是有争议的,而且您的资源很可能已经被强制从缓存中移出。

缺点是:

  • 发布期间,现场人员的页面可能会中断。例如,他们访问主页并下载 CSS,然后您使用新的 HTML 和 CSS 发布所有页面,然后相同的访问者查看另一个页面,因此获得新的 HTML,但仍然使用缓存的旧 CSS。这件事有多大,由你来决定。就我个人而言,对于重大更改,我对 CSS 文件 (stylesv2.css) 进行版本控制,但对于调整,我只能忍受这一点。很少会导致问题,并且用户经常会在页面看起来错误时重新加载页面。显然,对于某些网站来说,这可能有点简单,这可能不是一个选择。
  • 所有性能工具(例如 Google 的 Page Insights)都会标记您的到期时间较短 - 即使您出于充分的理由明确做出了该选择 - 因为他们(在我看来是错误的)认为较长的到期时间总是更好。比什么都烦人。

在我看来,ETag 非常无用,因为它们的实施很差。 Apache 默认情况下使用文件大小和修改时间的组合 - 正如您正确指出的那样,这可能无法识别文件内容是否已更改。 Inode 基本上就是磁盘上的文件引用,所以类似。在使用负载均衡器和多个 Web 服务器时也不建议这样做,因为每个服务器的 inode 都会不同(这就是默认情况下不再使用它的原因)。内容的散列会更好(尽管可能会更慢)。但 Apache 上的 Etags 的主要问题是,当您对数据进行 gzip 压缩时(您应该这样做),它们不起作用!请参阅我的博客文章:https://www.tunetheweb.com/performance/http-performance-headers/etag/。因此,您不应该在 Apache 上使用 Etag。而且,如上所述,它们对于小型资源(例如您希望压缩的文本资源)来说相当无用。最后修改的几乎一样好,并且没有 gzip 压缩资源的错误。

拥有适当的缓存是您可以对站点进行的最大性能改进之一。如果没有它,当您浏览网站时,无论您的服务器或访问者计算机的速度有多快,网站都会感觉缓慢且滞后。有了它,即使服务器速度很慢,网站也会感觉敏捷且响应迅速。然而,正如您所注意到的,它确实使事情变得复杂,因此需要好好思考如何正确设置它。

我在这里更详细地介绍了如何配置 Apache:https://www.tunetheweb.com/performance/http-performance-headers/caching/

希望这对您有所帮助 - 即使它有点啰嗦,而且不幸的是并没有给您提供您无疑正在寻找的快速解决方案!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在apache中控制浏览器缓存更改js和css文件的最佳方法? 的相关文章

  • 将 C# 3D 数组移植到 JS 3D 数组

    我开发了一个 C 库 它在 3 个项目中使用 这些项目在特定的代码段中中继 不过 我仍然需要在 javascript 中使用该代码 所以将其导出 问题是 我认为我无法复制同样的逻辑 比如这个问题我想了好几天也没有得出答案 在 C 库中 我有
  • 如何连接我的 angular2 应用程序 javascript 文件

    对于我的 Angular2 TypeScript 应用程序 我将所有 js 文件合并到一个 app min js 文件中 然后 System import 将此文件导入到我的 index html 页面 然后我得到一个同一模块文件中的多个匿
  • javaScript从单个值数组返回一个新的成对值数组[重复]

    这个问题在这里已经有答案了 可能的重复 将数组分割成块 https stackoverflow com questions 8495687 split array into chunks 我正在尝试将值数组转换为新的配对值数组 例如我需要转
  • 单击链接时如何将另一个 JSP 页面注入到

    我在一个JSP页面中有两个不同的部分 其中一个包含链接菜单 单击时 div2 id content 会相应加载不同的页面 我正在做类似的事情 div ul class navbar li a href Login jsp Login a l
  • 为什么 jQuery 的 .change() 事件仅在单击鼠标右键时触发?

    我在使用 jquery 时遇到了问题 change 当我修改输入元素时发生事件 据说 每当我对所述元素进行实时更改时 该事件就会触发 但就我而言 它仅在我按下右键单击按钮后才会触发 这是我的代码laravel框架 HTML div clas
  • CSS/XHTML 菜单 - 在所有浏览器中工作 - IE6 帮助

    我发现这个菜单正是我想要的 它适用于所有现代浏览器和 IE 7 8 我需要找到一个修复程序才能在 IE6 中工作 任何帮助将不胜感激 http lab returnwt net htmlcss tabmenu http lab return
  • onbeforeunload 或单击浏览器后退按钮需要帮助

    如果用户单击浏览器的后退按钮 那么我希望出现提示并要求确认 如果用户单击 确定 那么它应该导航到xx html 如果用户单击 取消 则应阻止导航 我怎样才能做到这一点 注意 我已经尝试过onbeforeunload方法 但它适用于所有导航操
  • 缩放对象上的弹跳动画

    拥有对象比例 然后在返回到原始比例因子之前以该比例因子执行弹跳动画的最佳方法是什么 我意识到我可以做一些事情 比如将其缩放到 2 2 然后 1 8 然后 2 0 但我正在寻找一种方法 您只需在比例因子上执行弹跳动画 因为我的比例因子会改变
  • 将 HTML 编辑器的内容保存为桌面上的 HTML 文件

    我想通过单击按钮来保存 TinyMce HTML 编辑器的内容 TinyMce 是本地安装的 我在 Chrome 中使用它 我见过这个answer https stackoverflow com a 30740104 3154274然后on
  • 在 Promise 中中止 ajax 请求

    我正在构建一个表单验证并学习承诺 我决定使用承诺模式实现异步验证函数 var validateAjax function value return new Promise function resolve reject ajax data
  • 使用 CSS 网格布局跨越所有列/行的项目

    随着 CSS 网格布局模块很快在 Firefox 和 Chrome 中发布 我想我应该尝试了解如何使用它 我尝试用一 个项目创建一个简单的网格a跨越所有行的左侧 其他项目 b c d e等 跨越各个行的右侧 跨越行右侧的项目数量是可变的 因
  • Angular 2.0 路由 - TS 2305 ...没有导出成员“ModulewithProviders”

    我正在关注一个角度2 0教程在 Angular JS 官方上site https angular io docs ts latest tutorial toh pt5 html并在路由练习结束时陷入困境 该代码上次有效 但前几天我点击 np
  • Google 脚本过滤一个值的范围

    我想过滤第 1 列中仅包含 Bob 特定值的行的 google 工作表范围 到目前为止 我的代码允许我过滤out第 1 列中有 Bob 的行 我需要相反 我想返回第 1 列中只有 Bob 的行 因此 其中 filterSettings 不是
  • Javascript:如何过滤对象数组并对结果求和

    我有一个对象数组 var example a 1 b 2 c 3 a 4 b 5 c 6 a 7 b 8 c 9 我正在尝试添加所有不对应的值c 我已经设法用 console log test filter x gt x c gt 3 过滤
  • 有没有办法避开 Google 路线中的特定道路或坐标?

    API 有一个航路点参数 以便 API 计算经过指定航路点的路线 有什么方法可以给出要避开的航路点而不是要经过的航路点 它 目前 尚未实施 有一个开放的功能请求 问题 214 影响方向的能力 例如 避免 路障 https code goog
  • Div 上的倾斜边框

    我正在尝试倾斜一个 div 类似于 使用 css 倾斜 div 的顶部而不倾斜文本 https stackoverflow com questions 13591584 slant the top of a div using css wi
  • 如何在JAVascript中删除具有相同ID但display='block'和display='none'的div

    我有超过 1 个 div 具有相同的 id 但其中一个具有 display block 和其他人有显示 无 我想删除所有具有 display none 的 div 请告诉最简单的方法 文档中多个元素具有相同的 id 是违反 W3 标准的 请
  • axios在自调用函数内部只调用一次(Internet Explorer)

    我有一个函数每 2 5 秒调用自己一次来检查后台运行的任务 它调用 axiosget如果响应错误 则返回一个 url 如果响应成功 我将停止该函数 这在 Chrome 和 Mozilla 上完美运行 但由于某种原因 它在 IE 版本 11
  • 如何在没有消息时隐藏 Bootstrap 警报框

    我用 Bootstrap 做了一个简单的警报框 如下所示 div class alertBox span class alert alert info bag session username span div When there is
  • Apollo 服务器,Graphql - 必须提供查询字符串

    我不确定我在这里做错了什么 我现在已经被困了一段时间 让我的突变在无服务器设置中与我的 apollo server lambda 一起运行 当我尝试运行这样的查询时 我的查询工作正常 mutation signIn username Som

随机推荐