您的位置:首页 > 理论基础 > 计算机网络

HTTP 缓存

2016-05-03 18:26 330 查看
从网络上加载资源是非常缓慢且浪费带宽的,所以,要是能将资源缓存起来就好了!

幸运的是,所有的浏览器都实现了HTTP缓存,我们要做的只是设定服务器响应的头部就行了!



当服务器响应的时候,总是包含HTTP头部,HTTP头部包含的信息有content-type, length, caching directives, validation token,等.

上例中,服务器返回了1024字节的响应,告诉浏览器缓存120秒,提供了一个验证令牌(“x234dff”)可以在响应过期之后来判别资源是否改变。

使用 ETags鉴别已缓存的资源

验证令牌(validation token)是在HTTP 头部中用ETag表示。

验证令牌允许资源更新检查

当响应超过120秒之后过期了,我们是不是重新下载资源呢?不需要!因为在响应返回的时候生成了一个随机的数字,也就是验证令牌,相当于HTTP响应的ID,用来鉴别http响应,所以如下所示,当我们再次发送请求的时候,会发送上一次响应个验证令牌,用If-None-Match字段表示,检查响应是否相同,如果响应相同,那么浏览器就不会再次下载资源。所以,所有我们需要做的就是检查你的服务器文档是否允许听过Etag令牌。



Remember

Tip: HTML5 Boilerplate 工程包含了 sample configuration files ,对于主流的服务器提供了详细的设置说明和例子。

Cache-Control字段

所有的资源通过Cache-Control HTTP 头部,定义了自己的缓存策略

Cache-Control表明了谁缓存响应,在怎样的情况下缓存响应以及缓存多久

Remember

Cache-Control 头部是在HTTP/1.1中定义的,并且重写了之前头部的一些字段(例如,Expires),所有的现代浏览器都支持Cache-Control,所以我们非常需要它



“no-cache” 和 “no-store”

“no-cache”表明在发送相同的url时,如果已存在验证令牌,还是会再次请求服务器一次,进行一次验证,但是不会进行资源的再次下载。

“no-store” 简单的表明资源不会被缓存,所以每一次请求都会下载一次资源。

“public” vs. “private”

如果响应被标记为 “public”那么响应可以被缓存,即使响应存在HTTP身份验证要求,即使响应的状态不是可缓存的。大多数的情况,”public“不是必须的,因为一旦使用了表明缓存事件的字段(例如max-age)就暗示了响应是可缓存的。

相反, “private” 表明可缓存,但是只是针对单个用户,例如一个HTML页面可以被用户的浏览器缓存,但是不可以被CDN缓存。

“max-age”

"max-age"表明了响应的响应的资源可以被再次使用的时间。- 例如. “max-age=60”表明了资源可以被缓存并且在下一个60秒内可以被再次使用。

定义最佳Cache-Control策略



理想状况下,你应该尽可能的保存多的资源,并且给每个资源设置较长的max-age 并且每个响应都要有一个验证令牌!

Cache-Control directivesExplanation
max-age=86400Response can be cached by browser and any intermediary caches (i.e. it is "public") for up to 1 day (60 seconds x 60 minutes x 24 hours)
private, max-age=600Response can be cached by the client’s browser only for up to 10 minutes (60 seconds x 10 minutes)
no-storeResponse is not allowed to be cached and must be fetched in full on every request.
According to HTTP Archive, amongst the top 300,000 sites (by Alexa rank), nearly half of all the downloaded responses can be cached by the browser, which is a huge savings for repeat pageviews and visits! Of course, that doesn’t mean that your particular application will have 50% of resources that can be cached: some sites can cache 90%+ of their resources, while others may have a lot of private or time-sensitive data that can’t be cached at all.

并不是缓存率越高,网站就越好,因为私有亦或对时间敏感的数据时不能被缓存的!

监听你的网站上哪些资源是可以被缓存的,并设置合理的max-age.

更新已缓存的数据

本地化已经缓存的数据允许我们使用,直到其“过期”

在URL中嵌入一个文件内容fingerprint允许客户端强制下载最新版本的资源。

为了最优的表现,每个应用需要定义它们自己的缓存等级。Each application needs to define its own cache hierarchy for optimal performance

例如我们更新了css文件,但是浏览器缓存了没有更新的css文件,并且缓存的css文件木有过期,我们想让浏览器加载最新的css文件,怎么办?我们除了改变资源加载的url没有任何办法。

我们可以在文件名中加入用户自定义的文件id,亦或版本号——例如e.g. style.x234dff.css,来让资源重新加载。



解释上面的代码:

HTML文件标价了no-cache表明每一次url请求时都将进行检查并下载最新版本的资源。我们在css和javascript文件中都加入了文件的fingerprint,所以,如果css和js文件内容有所改变的话,文件名也会改变,url就会改变,html就会自动下载最新的资源。

css文件可以被浏览器和中间商(例如CDN)缓存,我们设置css周期为1年,我们可以设置更久,因为一旦文件内容有所改变,文件会姿容加载。

js文件只能被浏览器缓存,cdn等中间商不能缓存。

图片命名没有任何的版本号亦或fingerprint添加,并且设置缓存为1年。

缓存优化清单

同样的资源使用一样的url: 如果一样的资源但是用不同个url来加载的话,同样的资源将会下载多次!

确保服务器提供了验证令牌(ETag): 资源没有改变时,验证令牌减少了资源下载次数。

确认哪些资源可以被中间商缓存: 对所有用户都可以相同的资源可以使用例如cdn等中间商缓存

为每个资源设置最佳的缓存周期: 不同的资源有不同的刷新请求,所以,为每个资源设置最佳的缓存周期。

分离缓存文件: 一些资源更新频繁,比如js文件中的函数亦或css中的某些样式。可以将这些常更新的内容在大文件中分离出来,成为单独的文件,这样可以让剩余的不常更新的文件缓存更久,并且让更新受重新获取文件时,文件大小最小。

原文:https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: