Tom*_*Tom 35 html javascript css apache caching
我一直在寻找缓存网站资产的方法,并注意到大多数类似于我的网站使用查询字符串来覆盖缓存(例如:/css/style.css?v=124942823)
之后,我注意到每当我保存我的style.css文件时,最后修改的标题都被"更新",使查询字符串变得不必要.
所以我想知道:
谢谢!
AD7*_*six 66
为什么这么多网站使用"查询字符串"方法,而不是让最后修改的标题工作?
更改查询字符串会更改网址,确保内容"新鲜".
我应该取消设置Last-modified标头并使用查询字符串吗?
不,虽然这几乎是正确的答案.
网络上使用了三种基本的缓存策略:
为了说明这三种情况,请考虑以下情形:
用户第一次访问网站,加载十页并离开.每个页面加载相同的css文件.对于上述每个缓存策略,将提出多少请求?
在这种情况下,应该清楚的是,没有任何其他因素影响结果,对css文件的10个请求将导致它被发送到客户端(浏览器)10次.
如果使用Last-Modified或Etag,则还会有10个请求.但是其中9个只是标题,并且没有身体被转移.客户端使用条件请求来避免重新下载已有的东西.以此网站的css文件为例.
第一次请求文件时,会发生以下情况:
$ curl -i http://cdn.sstatic.net/stackoverflow/all.css
HTTP/1.1 200 OK
Server: cloudflare-nginx
Date: Mon, 12 May 2014 07:38:31 GMT
Content-Type: text/css
Connection: keep-alive
Set-Cookie: __cfduid=d3fa9eddf76d614f83603a42f3e552f961399880311549; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.sstatic.net; HttpOnly
Cache-Control: public, max-age=604800
Last-Modified: Wed, 30 Apr 2014 22:09:37 GMT
ETag: "8026e7dfc064cf1:0"
Vary: Accept-Encoding
CF-Cache-Status: HIT
Expires: Mon, 19 May 2014 07:38:31 GMT
CF-RAY: 1294f50b2d6b08de-CDG
.avatar-change:hover{backgro.....Some KB of content
Run Code Online (Sandbox Code Playgroud)
对同一网址的后续请求如下所示:
$ curl -i -H "If-Modified-Since:Wed, 30 Apr 2014 22:09:37 GMT" http://cdn.sstatic.net/stackoverflow/all.css
HTTP/1.1 304 Not Modified
Server: cloudflare-nginx
Date: Mon, 12 May 2014 07:40:11 GMT
Content-Type: text/css
Connection: keep-alive
Set-Cookie: __cfduid=d0cc5afd385060dd8ba26265f0ebf40f81399880411024; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.sstatic.net; HttpOnly
Cache-Control: public, max-age=604800
Last-Modified: Wed, 30 Apr 2014 22:09:37 GMT
ETag: "8026e7dfc064cf1:0"
Vary: Accept-Encoding
CF-Cache-Status: HIT
Expires: Mon, 19 May 2014 07:40:11 GMT
CF-RAY: 1294f778e75d04a3-CDG
Run Code Online (Sandbox Code Playgroud)
请注意,没有正文,响应是304 Not Modified.这告诉客户端它已经拥有的内容(在本地缓存中)仍然是新鲜的.
这并不是说这是最佳方案.使用诸如chrome开发人员工具的网络选项卡之类的工具,您可以准确地查看请求需要多长时间,以及执行什么操作:
由于响应没有正文,响应时间会少得多,因为要传输的数据较少.但是,是仍然响应.还有就是仍然是所有连接到远程服务器的开销.
如果没有etags,没有最后修改的标头,并且将来只有一个过期标头集 - 只有第一次访问url才会导致与远程服务器的任何通信.这是众所周知的?更好的前端性能的最佳实践.如果是这种情况,对于后续请求,客户端将从其自己的缓存中读取内容,而根本不与远程服务器通信.
这具有明显的性能优势,这对于延迟可能很大的移动设备尤其重要(温和地说).
它是绕过客户端的缓存,网站使用查询参数.当内容更改(或者发布新版本的站点)时,将修改查询参数,因此在URL更改时将请求该文件的新版本.与每次更改文件时重命名文件相比,这项工作更少/更方便,但是没有问题,
使用查询字符串可防止代理缓存,在下面的引用中,作者证明来自浏览器< - >代理缓存服务器< - >网站的请求不使用代理缓存:
加载mylogo.gif?v = 1.2两次(清除其间的缓存)会产生以下标题:
Run Code Online (Sandbox Code Playgroud)>> GET http://stevesouders.com/mylogo.gif?v=1.2 HTTP/1.1 << HTTP/1.0 200 OK << Date: Sat, 23 Aug 2008 00:19:34 GMT << Expires: Tue, 21 Aug 2018 00:19:34 GMT << X-Cache: MISS from someserver.com << X-Cache-Lookup: MISS from someserver.com >> GET http://stevesouders.com/mylogo.gif?v=1.2 HTTP/1.1 << HTTP/1.0 200 OK << Date: Sat, 23 Aug 2008 00:19:47 GMT << Expires: Tue, 21 Aug 2018 00:19:47 GMT << X-Cache: MISS from someserver.com << X-Cache-Lookup: MISS from someserver.com
这里很清楚,第二个响应没有被代理服务:缓存响应标头说MISS,Date和Expires值改变,并且拖尾stevesouders.com访问日志显示两个命中.
这不应该掉以轻心 - 当访问位于世界另一端的物理网站时,响应时间可能非常慢.从位于路径上的代理服务器获得答案可能意味着网站之间的区别是否可用 - 在永久缓存资源的情况下,这意味着在使用验证请求的情况下,第一次加载网址的速度很慢意味着整个网站将是缓慢的.
"最佳"解决方案是版本控制文件,以便每当内容发生变化时,网址也会发生变化.通常,这将作为构建过程的一部分自动化.
然而,近乎妥协的是实现重写规则,如
# ------------------------------------------------------------------------------
# | Filename-based cache busting |
# ------------------------------------------------------------------------------
# If you're not using a build process to manage your filename version revving,
# you might want to consider enabling the following directives to route all
# requests such as `/css/style.12345.css` to `/css/style.css`.
# To understand why this is important and a better idea than `*.css?v231`, read:
# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpe?g|gif)$ $1.$3 [L]
</IfModule>
Run Code Online (Sandbox Code Playgroud)
通过这种方式foo.123.css
,服务器处理请求foo.css
- 这具有使用查询参数进行缓存清除的所有优点,但没有禁用代理缓存的问题.
归档时间: |
|
查看次数: |
15513 次 |
最近记录: |