浏览器 缓存机制 介绍和使用
浏览器 缓存有哪几种?
浏览器缓存是性能优化的一个重要手段,对于理解缓存机制而言也是很重要的
强缓存
强缓存两个相关字段, 「Expires」 , 「Cache-Control」
「强缓存分为两种情况,一种是发送 HTTP 请求,一种不需要发送。」
首先检查强缓存,这个阶段 不需要发送 HTTP 请求。 通过查找不同的字段来进行,不同的 HTTP 版本所以不同。
HTTP1.0 版本,使用的是 Expires,HTTP1.1 使用的是 Cache-Control
Expires
Expires
即 过期时间,时间是相对于服务器的时间而言的,存在于服务端返回的响应头中 ,在这个过期时间之前可以直接从缓存里面获取数据,无需再次请求,过期时就会重新向服务器发起请求。比如下面这样:
Expires:Mon, 29 Jun 2020 11:10:23 GMT
这个方式有一个问题: 「服务器的时间和浏览器的时间可能并不一致」 ,所以 HTTP1.1 提出新的字段代替它。
Cache-Control
这个字段采用的时间是 过期时长 ,对应的是 max-age 。下面代表该资源返回后 6000 秒,可以直接使用缓存
Cache-Control:max-age=6000
注意点:
- 当 Expires 和 Cache-Control 同时存在时,优先考虑 Cache-Control。
- 当然了,当缓存资源失效了,也就是没有命中强缓存,接下来就进入协商缓存
协商缓存
强缓存失效后,浏览器在请求头中携带响应的 缓存 Tag
来向服务器发送请求,服务器根据对应的 tag,来决定是否使用缓存 。
缓存分为两种, 「Last-Modified」 和 「ETag」 。两者各有优势,并不存在谁对谁有 绝对的优势
,与上面所讲的强缓存两个 Tag 所不同。
Last-Modified
这个字段表示的是 「最后修改时间」 。在浏览器第一次给服务器发送请求后, 服务器会在响应头中加上这个字段 。浏览器接收到后, 「如果再次请求」 ,会在请求头中携带 If-Modified-Since
字段,这个字段的值也就是服务器传来的最后修改时间。
服务器拿到请求头中的 If-Modified-Since
的字段后,其实会和这个服务器中 该资源的最后修改时间
对比:
- 如果请求头中的这个值小于最后修改时间,说明是时候更新了。返回新的资源,跟常规的 HTTP 请求响应的流程一样。
- 否则返回 304,告诉浏览器直接使用缓存
ETag
ETag 是服务器根据当前文件的内容,对文件生成唯一的标识 ,比如 MD5 算法,只要里面的内容有改动,这个值就会修改,服务器通过把响应头把该字段给浏览器。浏览器接受到 ETag 值,会在下次请求的时候,将这个值作为 「 If-None-Match
」 这个字段的内容,发给服务器。服务器接收到 「If-None-Match」 后,会跟服务器上该资源的 「ETag」 进行比对
- 如果两者一样的话,直接返回 304,告诉浏览器直接使用缓存,
- 如果不一样的话,说明内容更新了,返回新的资源,跟常规的 HTTP 请求响应的流程一样
两者对比
性能上, Last-Modified
优于 ETag
, Last-Modified
记录的是时间点,而 Etag
需要根据文件的 MD5 算法生成对应的 hash 值。
精度上, ETag
> Last-Modified
- 编辑了资源文件,但是文件内容并没有更改,这样也会造成缓存失效。
- Last-Modified 能够感知的单位时间是秒,如果文件在 1 秒内改变了多次,那么这时候的 Last-Modified 并没有体现出修改了。
「如果两种方式都支持的话,服务器会优先考虑 ETag」
缓存位置
接下来我们考虑使用缓存的话,缓存的位置在哪里呢
浏览器缓存的位置分为四种 ,优先级从高到低排列分别
- Service Worker
- Memory Cache
- Disk Cache
- Push Cache
Service Worker
这个应用场景比如 PWA,它借鉴了 Web Worker 思路,由于它脱离了浏览器的窗体,因此无法直接访问 DOM。它能完成的功能比如: 离线缓存
、 消息推送
和 网络代理
,其中 离线缓存
就是 「Service Worker Cache」 。
Memory Cache
内存缓存,从效率上讲它是最快的,从存活时间来讲又是最短的,当渲染进程结束后,内存缓存也就不存在了。
Disk Cache
存储在磁盘中的缓存,从存取效率上讲是比内存缓存慢的,优势在于存储容量和存储时长
两者对比,主要的策略
内容使用率高的话,文件优先进入磁盘
比较大的 JS,CSS 文件会直接放入磁盘,反之放入内存
Push Cache
推送缓存
总结
- 首先检查
Cache-Control
, 尝鲜,看强缓存是否可用。如果可用的话,直接使用 - 否则进入协商缓存,发送 HTTP 请求,服务器通过请求头中的
If-Modified-Since
或者If-None-Match
字段检查资源是否更新 - 资源更新,返回资源和 200 状态码。
- 否则,返回 304,直接告诉浏览器直接从缓存中去资源。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 浏览器工作原理与实践
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论