难受就摸头盖骨

浅谈 浏览器缓存 前端必备

来源:Loong Panda

缓存

什么是缓存?
	当我们第一次访问网站的时候,电脑会把网站上的图片和数据下载到电脑上,当我们再次访问的时候,网站就会从电脑中直接加载出来,这就是缓存。比如我们访问网页点击后退功能的时候,加载的非常快,这就是缓存的优势。

缓存规则:
	来源于服务器(如:nginx),大部分web服务器都默认开启协商缓存

缓存优点:
	1. 缓存服务器压力,不用每次都去请求某些数据了
	2. 提升性能,打开本地资源肯定会比请求服务器更快
	3. 减少带宽消耗,当我们使用缓存时,只会产生很小的网络消耗。

缓存的分类:
	1.强缓存
	2.协商缓存
	两者是主次的关系.

浏览器缓存过程: 首次请求时,浏览器根据服务器的应答respon Header来判断是否对资源进行缓存,,浏览器就会把资源缓存在memory cache 或 disk cache中。 再次请求时,首先,判断是否为强缓存,是再判断是否过期,没有过期就直接返回状态码200,从本地缓存中拿数据,过期则自动转为协商缓存(强缓存过期或者Cache-Control的值为no-cache就是协商缓存),接着携带字段访问服务器,服务端对比字段是否变化来判断资源是否更新符合,没变化代表没更新,返回状态码304,变化则代表更新了,返回全新资源,浏览器在缓存,周而复始。

强缓存与协商缓存的区别:
	强缓存不发请求到服务器,所以有时候资源更新了浏览器还不知道,但是协商缓存会发请求到服务器,所以资源是否更新,服务器肯定知道。


完整的缓存过程示意图:如下:

 

强缓存

强缓存: 
	如果响应头中有expires、pragma或cache-control字段,代表是强缓存,当我们首次访问URL的时候,浏览器就会把资源缓存在memory cache 或 disk cache中,再次访问时,不会向服务器发送请求,直接从缓存中读取资源,但是会返回200的状态码。

区别:
	Cache-Control 使用的是相对时间
	Expires 指定的是具体的过期时间而不是秒数。
	Cache-Control 和 Expires同时使用的话,Cache-Control 会覆盖Expires

 

协商缓存

协商缓存:强缓存过期后或者Cache-Control 的值为 no-cache

当浏览器判断不是强缓存,就会向服务器发请求,判断是否是协商缓存。如果是,服务器会返回304 Not Modified,浏览器从缓存中加载。

设置协商缓存:
通过Last-Modified和If-Modified-Since字段
1、浏览器第一次向服务器发请求,服务器返回资源并在response header加上Last-Modified字段,表示资源最后修改的时间。
2、浏览器再次请求这个资源时,请求头会加上If-Modified-Since字段。若这两个字段一样,说明资源没有修改过,返回304Not Modified,浏览器从缓存中获取资源。若这两个字段不一样,说明资源修改过,服务器正常返回资源。

控制协商缓存的字段: 
	1. Last-Modified (详细见页面末尾) 
	2. If-Modified-Since和Etag 
	3. If-None-Match, 注: Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

 

 

协商缓存的特殊情况

实际应用也会有服务器上资源有变化,但最后修改时间没更新的情况,这个时候就需要用到ETag / If-None-Match了。
1、浏览器第一次向服务器请求,服务器返回资源并在response header上加ETag字段。表示资源本身,资源有变化,则该字段有变化。
2、浏览器再次向服务器请求这个资源时,请求头携带If-None-Match字段。若这两个字段相同,则代表资源没有变化,服务器返回304Not Modified,浏览器从缓存中加载。若两个字段不同,证明资源有变动,服务器正常返回资源。

 

浏览器缓存位置

浏览器缓存位置

缓存查找顺序: 
	Service Worker –> Memory Cache –> Disk Cache –> Push Cache。

1 Service Worker
是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的

2 Memory Cache
内存中的缓存,主要包含的是当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快,内存缓存虽然读取高效,可是缓存持续性很短,会随着进程的释放而释放。一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。

3 Disk Cache
存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。
在所有浏览器缓存中,Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。并且即使在跨站点的情况下,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。绝大部分的缓存都来自 Disk Cache。

4 Push Cache
Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。

 

缓存存放位置、类型及读取

浏览器的缓存存放在哪里?
	1) from memory cache 代表使用内存中的缓存. 存储对象:js 和 css
	2) from disk cache。代表使用的是硬盘中的缓存. 存储对象: css

浏览器读取缓存的顺序为: memory –--> disk
	1) 因为memory是放在进程的内存当中的, 也就是内存存储,而内存存储有"快速读取"的优势, 所以如果进程没有关闭(浏览器标签页没有关闭),从内存读取的更有效率,因此,memory的优先级比disk高.

读取缓存的场景:
	访问网页 –> 200 服务器返回
	重新打开网页 –> 200(from disk cache) –>
	刷新 –> 200(from memory cache)

 

 

参数介绍

1、Cache-Control:

Cache-Control: 设置相对过期时间

参数:
 no-cache: 并不意味着不缓存。它的意思是在使用缓存资源之前,它必须经过服务器的检查
 no-store: 才是告诉浏览器不要缓存它
 private(默认): 只能在浏览器中缓存, 而不能由共享(代理服务器)缓存进行缓存
 public: 可以被任何缓存区缓存, 如: 浏览器、服务器、代理服务器等.
 max-age: 生存时间,相对过期时间, 即以秒为单位的缓存时间.
 no-cache, private: 打开新窗口时候重新访问服务器, 若设置max-age, 则缓存期间不访问服务器.
 - private, 正数的max-age: 后退时候不会访问服务器.
 - no-cache, 正数的max-age: 后退时会访问服务器.

2、Expires:

Expires 设置以分钟为单位的绝对过期时间,
 优先级比Cache-Control低, 同时设置Expires和Cache-Control则后者生效. 也就是说要注意一点: Cache-Control的优先级高于Expires
expires起到控制页面缓存的作用,合理配置expires可以减少很多服务器的请求, expires的配置可以在http段中或者server段中或者location段中. 比如控制图片等过期时间为30天, 可以配置如下:

location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ { root /var/www/img/; expires 30d; }

 

3、Last-Modified:

该资源的最后修改时间, 在浏览器下一次请求资源时, 浏览器将先发送一个请求到服务器上, 并附上If-Unmodified-Since头来说明浏览器里缓存资源的修改时间, 用于服务器进行对比,判断是否有修改

需要注意: 1) Last-Modified属性通常和Expires或Cache-Control属性配合使用, 因为即使浏览器设置缓存, 当用户点击”刷新”按钮时, 浏览器会忽略缓存继续向服务器发送请求, 这时Last-Modified将能够很好的减小回应开销. 2) ETag将返回给浏览器一个资源ID, 如果有了新版本则正常发送并附上新ID, 否则返回304, 但是在服务器集群情况下, 每个服务器将返回不同的ID, 因此不建议使用ETag.

 

ngxin配置示例

server {
    listen       443;
    #域名
    server_name  www.dev.163.com;
    #字符集
    charset utf-8;
    ssl                  on;
    ssl_certificate      /daka/program/nginx/conf/server.cer;
    ssl_certificate_key  /daka/program/nginx/conf/server.key;
    ssl_session_timeout  5m;
    ssl_protocols  SSLv2 SSLv3 TLSv1;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;
    #设置浏览器缓存
    add_header Cache-Control no-cache;
    add_header Cache-Control private;
    location /yp {
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://192.168.0.221:8082/yp/yp;

        if ($request_filename ~* .*.(html|htm)$)
         {
         expires -1s;
         }
         if ($request_filename ~* .*.(gif|jpg|jpeg|png|bmp|swf)$)
         {
         expires 30d;
         }
         if ($request_filename ~ .*.(js|css)$)
         {
         expires 12h;
         }
    }
}

 

三种刷新操作对 http 缓存的影响

正常操作:强制缓存有效,协商缓存有效。 操作行为:地址栏输入 url,跳转链接,前进后退等。
手动刷新:强制缓存失效,协商缓存有效。 操作行为:f5,点击刷新按钮,右键菜单刷新。
强制刷新:强制缓存失效,协商缓存失效。 操作行为:ctrl + f5,shift+command+r。

 

访问链接:Loong Panda

 

posted @ 2022-05-27 15:44  longpanda_怪怪哉  阅读(215)  评论(0编辑  收藏  举报
下定决心了,要把写不出代码就摸后脑勺的习惯给改了! 如果可以~单身待解救~~