HTTP强缓存与协商缓存

应用场景

前端代码打包之后的生成的静态资源就要发布到静态服务器上,需要做运维配置。
gzip和设置缓存是必不可少的。这两项是最直接影响到网站性能和用户体验的。

缓存可以减少了不必要的数据传输,节省带宽;减少服务器的负担,提升网站性能;加快了客户端加载网页的速度
但是需要注意:

资源如果有更改但是客户端不及时更新会造成用户获取信息滞后

所以掌握缓存的原理,更加合理的配置缓存是非常重要滴。

强缓存

强制
当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件做了缓存配置,由服务端控制缓存的时间、缓存类型。
即respone header 的cache-control,常见的设置是max-age public private no-cache no-store等

max-age=xxx
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200
有效期内客户刷新操作,就向服务器发http请求

  • immutable 即使用户刷新页面,浏览器也不会发起请求,会直接从本地磁盘或者内存中读取缓存并返回200状态
  • public 客户端和代理服务器都可以缓存该资源
  • private 只让客户端可以缓存该资源;代理服务器不缓存
  • no-cache 跳过设置强缓存,但是不妨碍协商缓存。一般,只有在强缓存失效才开始协商缓存的。
  • no-store 客户端、代理服务器都不缓存,也就没有所谓的强缓存、协商缓存。

综上
强缓存就是给资源设置个过期时间,客户端每次请求资源时都会看是否过期;只有在过期才会去询问服务器。
当客户端请求该资源时发现其过期了,就会去请求服务器了,而这时候去请求服务器的这过程就可以设置协商缓存。

协商缓存

协商缓存就是需要客户端和服务器两端进行交互的。

response header里面的设置
etag:文件hash,标识文件状态,改动文件了就变了
用webpack打包的时候,每个资源都会有。如: app.js打包后变为 app.c20abbde.js,加个唯一hash,也是为了解决缓存问题。
last-modified:文件的修改时间,精确到秒

每次请求返回的每个文件携带 response header 中的 etag和 last-modified,下次请求时在 request header 就把信息携带上,服务端把你带过来的标识进行对比,如果更改就返回200状态码、新资源,反之返回304状态码–>客户端用缓存的老资源。

在客户端重新向服务端发起请求时的etag、last-modified,在request header中换了key名,if-none-matched、if-modified-since

HTTP1.1中etag的出现,主要是为了解决几个last-modified比较难解决的问题:

  1. 文件的周期性更改,但是实质内容并不改变 管太宽
  2. if-modified-since能检查到的粒度是有限的,只能达到秒级的。文件修改(实质内容)非常频繁,甚至在秒以下的时间修改管太窄
  3. 某些服务器不能精确的得到文件的最后修改时间。管不到

设置强缓存与协商缓存

后端服务器如nodejs:
res.setHeader(‘max-age’: ‘3600 public’)
res.setHeader(etag: ‘5c20abbd-e2e8’)
res.setHeader(‘last-modified’: Mon, 24 Dec 2018 09:49:49 GMT)

index.html文件一般采用协商缓存不设置强缓存,用户每次请求index.html不拿浏览器缓存,直接请求服务器,用户能及时访问到新资源,如果服务端返回304,这时候再拿浏览器的缓存的index.html
其他资源采用强缓存 + 协商缓存。

memory cache: 它是将资源文件缓存到内存中。等下次请求访问的时候不需要重新下载资源,而是直接从内存中读取数据。脚本、字体、图片会存储到内存缓存中
disk cache: 它是将资源文件缓存到硬盘中。等下次请求的时候它是直接从硬盘中读取。非脚本会存放在硬盘中,比如css这些。
memory cache(内存缓存)退出进程时数据会被清除,而disk cache(硬盘缓存)退出进程时数据不会被清除。内存读取比硬盘中读取的速度更快。但是我们也不能把所有数据放在内存中缓存的,因为内存也是有限的。

缓存读取的原理:先从内存中查找对应的缓存,如果内存中能找到就读取对应的缓存,否则的话就从硬盘中查找对应的缓存,如果有就读取,否则的话,就重新网络请求。

你可能感兴趣的:(前端系统学习,计算机网络)