We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在前端开发中,我们在提到性能优化的时候总会提到一点:合理设置缓存。我们该如何从这方面入手来考虑提高网站性能呢?
我们都知道 HTML5 引入了应用程序缓存,可以在没有网络的情况下进行访问,同时,HTML5 还引入了 storage 本地存储。这些都属于应用缓存。
本篇文章主要内容是和浏览器缓存相关的,也可以说是 HTTP 缓存。
MDN 上是这样解释浏览器缓存的:
A browser cache holds all documents downloaded via HTTP by the user ... without requiring an additional trip to the server.
意思就是,浏览器缓存保存着用户通过 HTTP 获取的所有资源,再下一次请求时可以避免重复向服务器发出多余的请求。
HTTP
通俗的说,就是在你访问过一次某个网站之后,这个站点的文字、图片等所有资源都被下载到本地了,下次再访问该网站时判断是否满足缓存条件,如果满足就不用再花费时间去等待资源的获取了。
一般来说浏览器缓存可以分为两类:
我们需要知道的是,浏览器在加载资源时,会先判断是否命中强缓存再验证是命中协商缓存。
其它的的具体细节,稍后会展开来说。
浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。
header
从图中可以看出,强缓存一般是这样一个流程:
Expire
Cache-control
所以我们主要就是关注 Expire 和 Cache-control 这两个字段。
同样地,我们看看MDN中如何解释这个字段:
The Expires header contains the date/time after which the response is considered stale.
这个字段包含了一个时间,过了这个时间,响应将会失效。
也就是说,Expire 这个字段表示缓存到期时间,我们来打开一个网站并查看 Response Header 看看这个字段:
Response Header
Expires:Fri, 27 Oct 2017 07:55:30 GMT
可能在你查看这的时候发现时间不对啊,怎么都已经是过去了 ~
GMT 表示的是格林威治时间,和北京时间相差8小时。
GMT
上面的这个时间表示的是 2017年10月27日15:55:30。
2017年10月27日15:55:30
通过设置 Expire 来设置缓存有一个致命缺点:
可以看出,这个是个绝对时间,也就是说,如果我修改了客户端的本地时间,是不是就会导致判断缓存失效了呢。
既然不能设置绝对时间,那我就设置个相对时间呗。
在 HTTP/1.1 中,增加了一个字段 Cache-Control ,它包含一个 max-age 属性,该字段表示资源缓存的最大有效时间,这就是一个相对时间。
HTTP/1.1
Cache-Control
max-age
Cache-Control:max-age=600
这个表示的就是最大有效时间是 600s ,对的,它的单位是秒。
600s
Cache-Control 除了 max-age 属性之外还有一些属性:
现在基本上都会同时设置 Expire 和 Cache-Control ,Cache-Control 的优先级别更高。
当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据请求头中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。
304
从图中可以看出,协商缓存一般是这样一个流程:
If-Modify-Since
Etag
Not Modified
浏览器第一次请求资源的时候,服务器返回的 header 上会带有一个 Last-Modified 字段,表示资源最后修改的时间。
Last-Modified
Last-Modified: Fri, 27 Oct 2017 07:55:30 GMT
同样的,这是一个 GMT 的绝对时间。
当浏览器再次请求该资源时,请求头中会带有一个 If-Modified-Since 字段,这个值是第一次请求返回的 Last-Modified 的值。服务器收到这个请求后,将 If-Modified-Since 和当前的 Last-Modified 进行对比。如果相等,则说明资源未修改,返回 304,浏览器使用本地缓存。
If-Modified-Since
well,这个方法也是有缺点的:
所以,后来又引入一个 Etag。
Etag 一般是由文件内容 hash 生成的,也就是说它可以保证资源的唯一性,资源发生改变就会导致 Etag 发生改变。
hash
同样地,在浏览器第一次请求资源时,服务器会返回一个 Etag 标识。当再次请求该资源时, 会通过 If-no-match 字段将 Etag 发送回服务器,然后服务器进行比较,如果相等,则返回 304 表示未修改。
If-no-match
**Last-Modified 和 Etag 是可以同时设置的,服务器会优先校验 Etag,如果 Etag 相等就会继续比对 Last-Modified,最后才会决定是否返回 304。 **
当浏览器再次访问一个已经访问过的资源时,它会这样做:
The text was updated successfully, but these errors were encountered:
浏览器缓存知识小结及应用
Sorry, something went wrong.
从图中可以看出的图 在哪里
No branches or pull requests
在前端开发中,我们在提到性能优化的时候总会提到一点:合理设置缓存。我们该如何从这方面入手来考虑提高网站性能呢?
前言
我们都知道 HTML5 引入了应用程序缓存,可以在没有网络的情况下进行访问,同时,HTML5 还引入了 storage 本地存储。这些都属于应用缓存。
本篇文章主要内容是和浏览器缓存相关的,也可以说是 HTTP 缓存。
什么是浏览器缓存
MDN 上是这样解释浏览器缓存的:
意思就是,浏览器缓存保存着用户通过
HTTP
获取的所有资源,再下一次请求时可以避免重复向服务器发出多余的请求。通俗的说,就是在你访问过一次某个网站之后,这个站点的文字、图片等所有资源都被下载到本地了,下次再访问该网站时判断是否满足缓存条件,如果满足就不用再花费时间去等待资源的获取了。
浏览器缓存的分类
一般来说浏览器缓存可以分为两类:
我们需要知道的是,浏览器在加载资源时,会先判断是否命中强缓存再验证是命中协商缓存。
其它的的具体细节,稍后会展开来说。
强缓存
浏览器在加载资源时,会先根据本地缓存资源的
header
中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。从图中可以看出,强缓存一般是这样一个流程:
header
头中的Expire
和Cache-control
来判断是否满足规则;所以我们主要就是关注
Expire
和Cache-control
这两个字段。Expire
同样地,我们看看MDN中如何解释这个字段:
这个字段包含了一个时间,过了这个时间,响应将会失效。
也就是说,
Expire
这个字段表示缓存到期时间,我们来打开一个网站并查看Response Header
看看这个字段:可能在你查看这的时候发现时间不对啊,怎么都已经是过去了 ~
GMT
表示的是格林威治时间,和北京时间相差8小时。上面的这个时间表示的是
2017年10月27日15:55:30
。通过设置
Expire
来设置缓存有一个致命缺点:可以看出,这个是个绝对时间,也就是说,如果我修改了客户端的本地时间,是不是就会导致判断缓存失效了呢。
Cache-Control
既然不能设置绝对时间,那我就设置个相对时间呗。
在
HTTP/1.1
中,增加了一个字段Cache-Control
,它包含一个max-age
属性,该字段表示资源缓存的最大有效时间,这就是一个相对时间。这个表示的就是最大有效时间是
600s
,对的,它的单位是秒。Cache-Control
除了max-age
属性之外还有一些属性:现在基本上都会同时设置
Expire
和Cache-Control
,Cache-Control
的优先级别更高。协商缓存
当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据请求头中的部分信息来判断是否命中缓存。如果命中,则返回
304
,告诉浏览器资源未更新,可使用本地的缓存。从图中可以看出,协商缓存一般是这样一个流程:
If-Modify-Since
或Etag
发送到服务器,确认资源是否更新;304
并且会显示一个Not Modified
的字符串,告诉浏览器使用本地缓存;Last-Modified,If-Modified-Since
浏览器第一次请求资源的时候,服务器返回的
header
上会带有一个Last-Modified
字段,表示资源最后修改的时间。同样的,这是一个
GMT
的绝对时间。当浏览器再次请求该资源时,请求头中会带有一个
If-Modified-Since
字段,这个值是第一次请求返回的Last-Modified
的值。服务器收到这个请求后,将If-Modified-Since
和当前的Last-Modified
进行对比。如果相等,则说明资源未修改,返回304
,浏览器使用本地缓存。well,这个方法也是有缺点的:
Last-Modified
并不会发生变化;Last-Modified
可不这样认为。所以,后来又引入一个
Etag
。Etag
Etag
一般是由文件内容hash
生成的,也就是说它可以保证资源的唯一性,资源发生改变就会导致Etag
发生改变。同样地,在浏览器第一次请求资源时,服务器会返回一个
Etag
标识。当再次请求该资源时, 会通过If-no-match
字段将Etag
发送回服务器,然后服务器进行比较,如果相等,则返回304
表示未修改。**
Last-Modified
和Etag
是可以同时设置的,服务器会优先校验Etag
,如果Etag
相等就会继续比对Last-Modified
,最后才会决定是否返回304
。 **总结
当浏览器再次访问一个已经访问过的资源时,它会这样做:
304
告诉浏览器使用本地缓存;The text was updated successfully, but these errors were encountered: