浏览器缓存机制

html-css06

浏览器缓存机制,第1张

有dns的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存。

DNS查询过程如下:

首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。

如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。

如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。

如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。

浏览器本地缓存失效后,浏览器会向CDN边缘节点发起请求。类似浏览器缓存,CDN边缘节点也存在着一套缓存机制。CDN边缘节点缓存策略因服务商不同而不同,但一般都会遵循http标准协议,通过http响应头中的

Cache-control: max-age 的字段来设置CDN边缘节点数据缓存时间。

当浏览器向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN节点就会向服务器发出回源请求,从服务器拉取最新数据,更新本地缓存,并将最新数据返回给客户端。 CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。

CDN 优势

CDN节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。

大部分请求在CDN边缘节点完成,CDN起到了分流作用,减轻了源服务器的负载。

http请求报文(request)

请求行

请求方法  空格  URL 空格  协议版本 回车符 换行符

请求头(通用信息头、请求头、实体头)

头部字段名 冒号  值  回车键 换行符

...

头部字段名 冒号  值  回车键 换行符

空行

回车符   换行符

实体主体(只有post请求有)

主体

http响应报文(response)

状态行

协议版本  空格  状态码 空格  状态码描述 回车符 换行符

响应头部

头部字段名 冒号  值   回车符 换行符

...

头部字段名 冒号  值   回车符 换行符

空行

回车符   换行符

响应正文

正文

浏览器初次向服务器发起请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存返回的结果,是则将请求结果和缓存标识存入浏览器缓存中

浏览器每次发起请求,都会现在浏览器缓存中查找该请求的结果以及缓存标识

浏览器                浏览器缓存        服务器

——————第一次发起http请求——————>

<——没有该请求的缓存结果和缓存标识————

——————————————发起http请求——————————————>

<——————————返回该请求结果和缓存规则————————————

——将请求结果和缓存标识存入浏览器缓存——>

强制缓存就是向浏览器缓存查找结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程

强制缓存的情况分为三种:

1、不存在该缓存结果和缓存标识,强制缓存失效,直接向服务器发起请求

2、存在该缓存结果和缓存标识,但结果已经失效,强制缓存失效,使用协商缓存

3、存在该缓存结果和缓存标识,且该结果没有失效,强制缓存生效,直接返回该结果

控制强制缓存的字段:Expires,Cache-Control

Expires 是 HTTP/1.0 控制缓存的字段,值为服务器返回该请求的结果缓存时间

即再次发送请求是,客户端时间 小于 Expires的值,直接使用缓存结果

Cache-Control 是HTTP/1.1的规则,主要用于控制网页缓存,主要取值为:

public:所有的内容都缓存(客户端和代理服务器都可以缓存)

private:所有内容只有客户端可以缓存(默认值)

no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

no-store:即不使用强制缓存,也不使用协商缓存

max-age=xxx:缓存内容将在xxx秒后失效

Expires 是一个绝对值

Cache-Control 中 max-age 是相对值,解决了 Expires时期 服务端与客户端 可能出现时间差的问题

注:Expires和Cache-Control同时存在时,只有Cache-Control生效

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

协商缓存的两种情况:

1、协商缓存生效,返回304,继续使用缓存

过程:

浏览器                 浏览器缓存     服务器

————————发起http请求————————>

<——该请求的缓存结果失效,只返回缓存标识——

————————携带该资源的缓存标识,发起http请求————————>

<—————————————304,该资源无更新————————————

——————获取该请求的缓存结果——————>

<——————返回该请求的缓存结果——————

2、协商缓存失败,返回200和请求结果

过程:

浏览器                 浏览器缓存     服务器

————————发起http请求————————>

<——该请求的缓存结果失效,只返回缓存标识——

————————携带该资源的缓存标识,发起http请求————————>

<————————200,资源已更新,重新返回请求和结果———————

——将该请求结果和缓存标识存入浏览器缓存中—>

协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的

控制协商缓存的字段:

(1) Last-Modified/If-Modified-Since:Last-Modified是服务器响应请求是,返回该资源文件在服务器最后被修改的时间;If-Modified-Since再次发起请求时,携带上次返回的Last-Modified的值,服务器将该字段值与该资源最后修改时间对比,决定是否用缓存

(2)Etag/If-None-Match:Etag服务器响应请求时,返回当前资源文件的一个唯一标识,由服务器生成之;If-None-Match是再次发起请求时,携带上次返回的唯一标识Etag的值,服务器收到后,将该字段值与该资源在服务器上的Etag对比,一致 则返回304,否则返回200

注:Etag/If-None-Match优先级高于Last-Modified/If-Modified-Since,同时存在时只有Etag/If-None-Match生效

浏览器缓存分为:内存缓存 和 硬盘缓存

内存缓存特性:

(1)快速读取:内存缓存会将编译解析后的文件,存入该进程的内存中,便于下次运行时快速读取

(2)时效性:一旦关闭进程,进程内存清空

硬盘缓存特性:

永久性:直接写入硬盘文件中

复杂、缓慢:读取缓存对该缓存存放的硬盘文件进行I/O操作,重新解析

from memory cache:使用内存中的缓存

from disk cache:使用硬盘中的缓存

浏览器读取顺序:memory ——>disk

浏览器将js和图片等文件解析执行后直接存入内存缓存中,F5刷新页面时,from memory cache(使用内存中的缓存)

css文件存入硬盘中,F5刷新页面时,from disk cache(使用硬盘中的缓存)

参考文章

https://segmentfault.com/a/1190000017962411

https://www.cnblogs.com/chengxs/p/10396066.html

浏览器缓存策略分为两种 强缓存 (本地缓存) 和 协商缓存 (弱缓存)。

浏览器在发请求前,先检查强缓存,若没有需要的内容(未命中),则发起请求判断是否需要用弱缓存。

强缓存 是不发起请求,直接使用缓存内的内容的。浏览器将 js 、 css 、 image 、 font-family 等存到内存(存小文件)或者磁盘(存大文件)中,下次用户再访问的时候就从内存中取,以便提升性能。

协商缓存 需要往后台发请求, 通过判断来决定是使用协商缓存。如果请求内容没发生变化,则请求返回304(服务器收到请求,但内容无变化),浏览器就用缓存内的内容。

如果服务器返回的响应标头中包含 Expires (时间戳),那么客户端发起请求的时间在 Expires 之前的话,就触发强缓存。

服务器在上一次响应请求时,返回一个带 Last-Modified 的响应头,值为一个时间戳,表示该资源最后一次在服务器修改的时间。当客户端再一次请求这个资源的时候, 请求头就会带上 If-Modified-Since ,值为上次服务器发来的 Last-Modified , 服务器收到后,就和该资源最后修改时间比对, 没变化就返回304, 触发协商缓存。

弊端 : 时间间隔最小为1s,如果请求的资源在1s内发生了改变,是可能会触发协商缓存的, 导致无法获取到最新的资源。

为解决间隔最小1s的问题, If-None-Match 和 Etag 就诞生了。 Etag 是由服务器生成的, 是每个资源的唯一标识字符串, 随资源变化而改变。 判断过程和http1.0的一致,请求的时候携带 If-None-Match ,然后服务器比较这两个值,没变化就返回304, 触发协商缓存。

弊端 : 占用服务器资源较多, 虽然准确度高,但是性能上不如 Last-Modified &If-Modified-Since 的方法。不过实际的影响不会很大, 基本上可以忽略不计。

即便我们没有配置缓存策略,浏览器也会采用自己的算法来缓存资源。

这是因为浏览器默认是有缓存的。

解决方法:调试前清除浏览器缓存,在浏览器设置界面中或使用快捷键直接清理缓存ctrl+shift+delete。

浏览器会缓存css或js文件,通过设置和改变版本号,浏览器就会重新下载新的js或css文件,在js或css后加?v=版本号的用法如下:css和js带参数(形如.css?v=与.js?v=或.css?version=与.js?version=)。