精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-06
最后修改:2009-08-08
注意,这里讲的是浏览器端的cache。关于Rails服务器端的cache,以后专门开题再讲。
总而言之,cache机制是为了减少发送request的次数(过期模型),还有就是减少发送整个response的机会以减少网络带宽的使用(验证模型)。
在HTTP协议里面,主要有三种控制cache的方式。
1. Cache-Control
Cache-Control有一系列的指令来告诉应该对cache采取怎样的处理,比如no-cache, no-store, max-age, must- revalidate等。Cache-Control也是唯一的显式指令。其它模式,比如过期模型和验证模型,都是隐式地告诉应该怎样处理cache。
Cache-Control有很多不同的指令。如果有明显的冲突,一般采用最严格的解释方式。
2. 过期模型(Expiration Model)
应用了过期模型,在设定的过期时限之前,不会向服务器发起真正的request,而是直接返回cache。
这种方式一般用在一些静态页面很多,或者基本上在一段时间内不会改变的页面上。比如google的主页一般在几个礼拜内都不会变化。
服务端通过Expires头或者Cache-Control的max-age指令来设定过期时间(后者的优先级更高,如果同时指定,后者覆盖前者)。
3. 验证模型(Validation Model)
当cache有一个旧的entry,想用它作为一个客户端请求的response时,它需要检查cache的entry是否仍可用(这里不是基于应用了过期模型的cache方式,而是默认cache方式)。这就是验证模型。
服务器端会进行验证,如果验证确实match,则返回304(Not Modified)状态码,但不会返回entity-body。否则则返回整个response(包括entity-body)。
验证模型可以使用时间、checksum等来进行验证。跟验证模型相关的指令有:last-modifed, if-modified-since, ETag, if-none-match等。
对于这三种模式在冲突时的优先级关系,我没有很好地去分析。但通过某些行为可以看出,Expire优先于Validation,而某些Cache-Control指令又能把Expires或者Validation干掉。
现代web服务器和浏览器对Cache的支持
用firebug跟踪了一下,发现现在的web服务器(即使是Mongrel)和浏览器对cache的工作做得相当好。对于如css,javascript,image等文件,都会自动采取验证模型来进行cache。
比如第一次对一个静态文件进行访问时,response header包含这样一个值:
Last-Modified Wed, 25 Mar 2009 15:07:30 GMT Etag"49ca48b2-1faca-140dbf"
后续的请求头里面会有如下一些值:
If-Modified-Since Wed, 25 Mar 2009 15:07:30 GMT If-None-Match "49ca48b2-1faca-140dbf" Cache-Control max-age=0
相应的response status code是304(Not Modified),且response header变成:
Connection close Date Mon, 06 Apr 2009 09:32:46 GMT Etag "49ca48b2-1faca-140dbf"
Rails对动态页面cache的支持
见http://guides.rubyonrails.org/caching_with_rails.html 的Conditional GET support部分。
Rails鼓励我们采取怎样的cache方式
Rails会默认为javascript,css,image等资源文件的path后面附加上文件的最后修改时间。为啥要这么做?很明显,Rails是在鼓励你使用过期模型去cache这些资源文件。
比如在Apache里,使用这样的配置来使这些静态资源文件被cache。 ExpiresActive On <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$"> ExpiresDefault "access plus 1 year" </FilesMatch> 添加了这个配置之后。对js等文件请求的reponse头里面就会多了如下两个header。
Cache-Control max-age=31536000 Expires Tue, 06 Apr 2010 09:28:49 GMT 在随后的请求中,只要文件还没过期,客户端就不需要再去发起request获取被Cache的资源。同时,一旦文件有任何改变,浏览器都能获取到新的文件。因为path已经根据最后修改时间改变。
唯一值得注意的是,因为浏览器限制对同一个地址一般最多同时发起两个请求,所以我们会使用了多台资源服务器(查看AssetTagHelper Doc 了解怎样使用多台资源服务器),那么保证每台服务器时间的同步是至关重要的。不然会因为资源服务器的随机选择,url后附着的时间戳经常改变,致使cache失效。
Cache的两条简单规则
对于现在的网站应用来说,我很同意以下的两条cache原则。
Don't cache HTML
1. Use 2. Use the
Cache everything else forever
1. For all other file types set an 2. Modify URLs by appending a query string in your HTML to any page element you wish to ‘expire’ immediately.
结束! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 2636 次